Mathematica中的条件列表值替换

500*_*500 2 conditional replace wolfram-mathematica

请考虑 :

dalist = Transpose@{{"Noise1",1,1,1,1,1},{"Blah", 1, 2, 3, 4, 5},
                   {"Noise2",2,2,2,2,2}, {"COGCondition", 1, 2, 1, 2, 1}}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

COGCondition1 = 10
COGCondition2 = 20
Run Code Online (Sandbox Code Playgroud)

给定"COGCondition"栏中的值,我想替换"Blah"列中的值,这样:

如果对于给定的行,"COGCondition"列中的值= 1,则"Blah"列中的值应等于COGCondition1(和2 - > COGCondition2)

期望的输出:

在此输入图像描述

我需要这个用于大型数据集并且我尝试使用Table并且Switch失败了.我可以轻松生成新列,但无法弄清楚如何使用替换值Switch.

rco*_*yer 7

对于替换规则,这非常简单:

dalist /.
  {x_?NumericQ, y_?NumericQ} :> 
  {Which[y==1, COGCondition1, y==2, COGCondition2], y}
Run Code Online (Sandbox Code Playgroud)

{{"Blah", "COGCondition"}, {10, 1}, {20, 2}, {10, 1}, {20, 2}, {10, 1}}.
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用 MapThread

MapThread[ 
    If[ !NumericQ[#2], #1,
      Which[#2==1, COGCondition1, #2==2, COGCondition2] ]&,
   Transpose@dalist]
Run Code Online (Sandbox Code Playgroud)

返回

{"Blah", 10, 20, 10, 20, 10}.
Run Code Online (Sandbox Code Playgroud)

编辑:在您的更新版本中dalist,您有四列:噪音,数据,噪音和条件.模式版本的更新很简单

dalist /.
  {a_, x_, b_, y_} :> 
  {a, Which[y==1, COGCondition1, y==2, COGCondition2], b, y}
Run Code Online (Sandbox Code Playgroud)

不幸的是,这有点脆弱,因为如果你改变条件的数量,它需要一些额外的工作.Leonid建议的方法是创建一个函数

Clear[COGCondition]
COGCondition[1] = 10
COGCondition[2] = 20
Run Code Online (Sandbox Code Playgroud)

然后这简化了更新代码

dalist /.
  {a_, x_, b_, y_Integer} :> {a, COGCondition[y], b, y}
Run Code Online (Sandbox Code Playgroud)

或者,您可以创建规则列表

conditions = { 1 -> 10, 2 -> 20 }
Run Code Online (Sandbox Code Playgroud)

那么改变的代码dalist就变成了

dalist /.
  {a_, x_, b_, y_Integer} :> {a, y /. conditions, b, y}
Run Code Online (Sandbox Code Playgroud)

如果您发现在x和之间有超过1列y,那么您的模式就是简单{a_, x_, b___, y_Integer}.或者,如果之前的列数x大于1,请使用{a___, x_, b_, y_Integer}.但是,它们不能一起工作,因为Mathematica需要知道列表中某个点的位置xy相对位置,或者它根本不会按预期运行(如果有的话).

但是,如果您知道列数,则可以使用PatternSequence.例如,如果你有3列噪音,你的数据,5列噪音,然后你有条件,你的替换规则就是

dalist /.
  {a:PatternSequence@@Array[_&,3], x_, 
   b:PatternSequence@@Array[_&,5], y_Integer} :> {a, y /. conditions, b, y}
Run Code Online (Sandbox Code Playgroud)

现在,PatternSequence@@Array[_&,3]可以编写PatternSequence[_, _, _],但通过使用Array它可以提供更大的灵活性.


编辑:索引变量形式COGCondition[n]或规则形式的一个难点是条件列是否包含1或2以外的值.最简单的解决方案是设置默认值,例如

COGCondition[_] := default (*where default may be defined elsewhere *)
Run Code Online (Sandbox Code Playgroud)

或添加到 conditions

_ :> default
Run Code Online (Sandbox Code Playgroud)

一种可能性是在Message遇到此默认值时发出一个可在其运行时提供反馈的情况.

另一种可能性是,如果遇到默认值,则保持数据列保持不变.为此,我们可以使用以下内容

COGCondition[1,_] := 10
(*define the rest of the known values as above*)
COGCondition[_,d_]:= default (*encountered only if the 1st var is unknown*)
Run Code Online (Sandbox Code Playgroud)

哪个会像

dalist /.
  {a_, x_, b_, y_Integer} :> {a, COGCondition[y, x], b, y}.
Run Code Online (Sandbox Code Playgroud)

为了使这与规则实现一起工作,我们创建conditions了一个接受当前数据值的函数

conditions[dat_] := { 1 -> 10, 2 -> 20, _ :> dat }
Run Code Online (Sandbox Code Playgroud)

它将更新代码更改dalist

dalist /.
  {a_, x_, b_, y_Integer} :> {a, y /. conditions[x], b, y}.
Run Code Online (Sandbox Code Playgroud)

注意,最后两种方法中的任何一种都可以与Message从上面发射a组合.

  • @Sjoerd,@ Mr.Wizard的实现遇到了同样的问题,它还依赖于定义`COGCondition`的值.例如,如果`y`列包含3,它将返回该值的`COGCondition [3]`.但是,规则公式将返回3,因为它没有匹配.这可以通过定义`COGCondition [_]:= default`或将`_:> default`添加到规则列表来解决. (2认同)

Mr.*_*ard 6

我会用:

dalist[[2 ;;, 2]] =
 dalist[[2 ;;, 4]] /. {1 -> COGCondition1, 2 -> COGCondition2};

dalist //TableForm
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

如果dalist不希望进行修改,则可以先复制,例如dalist2 = dalist,然后修改副本.

特别是如果条件列有很多值,我建议你按照之前的建议使用索引变量(COGCondition[1]).这看起来像:

dalist[[2 ;;, 2]] = COGCondition /@ dalist[[2 ;;, 4]];
Run Code Online (Sandbox Code Playgroud)

  • 或者,如果条件表达为规则列表:`conditions = {1-> 10,2-> 20}`,那么`dalist [[2 ;;,2]] = dalist [[2 ;;,4 ]] /.conditions`. (2认同)