使用替换规则相当简单:
dalist /.
{x_?NumericQ, y_?NumericQ} :>
{Which[y==1, COGCondition1, y==2, COGCondition2], y}
给予
{{"Blah", "COGCondition"}, {10, 1}, {20, 2}, {10, 1}, {20, 2}, {10, 1}}.
或者,您可以使用MapThread
MapThread[
If[ !NumericQ[#2], #1,
Which[#2==1, COGCondition1, #2==2, COGCondition2] ]&,
Transpose@dalist]
返回
{"Blah", 10, 20, 10, 20, 10}.
编辑:在dalist 的更新版本中,您有四列:噪声、数据、噪声和条件。模式版本的更新简直就是
dalist /.
{a_, x_, b_, y_} :>
{a, Which[y==1, COGCondition1, y==2, COGCondition2], b, y}
不幸的是,这有点脆弱,因为如果您更改条件的数量,它需要一些额外的工作。 Leonid 建议的方法是创建一个函数
Clear[COGCondition]
COGCondition[1] = 10
COGCondition[2] = 20
那么这就简化了更新代码
dalist /.
{a_, x_, b_, y_Integer} :> {a, COGCondition[y], b, y}
或者,您可以创建一个规则列表
conditions = { 1 -> 10, 2 -> 20 }
那么更改dalist的代码就变成了
dalist /.
{a_, x_, b_, y_Integer} :> {a, y /. conditions, b, y}
如果您发现在x 和y 之间有超过1 列,那么您的模式就是{a_, x_, b___, y_Integer}。或者,如果x 之前的列数大于一,则使用{a___, x_, b_, y_Integer}。但是,它们不能一起工作,因为 Mathematica 需要知道 x 和 y 相对于列表中某个点的位置,否则它不会按您预期的方式运行,如果有的话。
但是,如果您知道列数,则可以使用PatternSequence。例如,如果你有 3 列噪音,你的数据,5 列噪音,然后你的条件,你的替换规则将是
dalist /.
{a:PatternSequence@@Array[_&,3], x_,
b:PatternSequence@@Array[_&,5], y_Integer} :> {a, y /. conditions, b, y}
现在,PatternSequence@@Array[_&,3] 可以写成 PatternSequence[_, _, _],但使用 Array 可以提供更大的灵活性。
编辑:索引变量形式 COGCondition[n] 或规则形式的一个困难是条件列是否包含 1 或 2 以外的值。最简单的解决方案是设置一个默认值,例如
COGCondition[_] := default (*where default may be defined elsewhere *)
或添加到conditions
_ :> default
一种可能性是在遇到此默认值时发出Message,这将在其运行时提供反馈。
如果遇到默认值,另一种可能性是保持数据列不变。为此,我们可以使用以下方法
COGCondition[1,_] := 10
(*define the rest of the known values as above*)
COGCondition[_,d_]:= default (*encountered only if the 1st var is unknown*)
会像这样使用
dalist /.
{a_, x_, b_, y_Integer} :> {a, COGCondition[y, x], b, y}.
为了使这项工作与规则实现一起工作,我们将conditions 设为接受当前数据值的函数
conditions[dat_] := { 1 -> 10, 2 -> 20, _ :> dat }
将更新dalist的代码更改为
dalist /.
{a_, x_, b_, y_Integer} :> {a, y /. conditions[x], b, y}.
注意,最后两种方法中的任何一种都可以与从上方发出 Message 结合使用。