【问题标题】:Conditional list values replacement in MathematicaMathematica 中的条件列表值替换
【发布时间】:2011-08-19 20:52:24
【问题描述】:

请考虑:

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}}

COGCondition1 = 10
COGCondition2 = 20

考虑到“COGCondition”列中的值,我想替换“Blah”列中的值:

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

期望的输出:

对于大型数据集,我需要它,但我使用 TableSwitch 的尝试失败了。我可以轻松生成新列,但不知道如何使用 Switch 替换值。

【问题讨论】:

    标签: replace wolfram-mathematica conditional


    【解决方案1】:

    使用替换规则相当简单:

    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}
    

    如果您发现在xy 之间有超过1 列,那么您的模式就是{a_, x_, b___, y_Integer}。或者,如果x 之前的列数大于一,则使用{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}
    

    现在,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 结合使用。

    【讨论】:

    • 谢谢,但我必须承认我可以t get any of the above to work :-( I dont 理解 {{"Blah", ...}, {"COGCondition", ...}}。然而所有返回错误:-(
    • 抱歉,我只是想使用简写使其更具可读性:{"Blah", ...} = {"Blah", 1, 2, 3, 4, 5}{"COGCondition", ...} 也是如此。
    • @Leonid,我什至没有看到那个错误。谢谢。
    • @500,我修复了这个错误并添加了几种方法来使代码更灵活。
    • @Sjoerd,@Mr.Wizard 的实现遇到了同样的问题,它还依赖于定义 COGCondition 的值。例如,如果 y 列包含 3,它将返回该值的 COGCondition[3]。但是,规则制定将返回 3,因为没有匹配项。这可以通过定义COGCondition[_]:=default 或将_ :> default 添加到规则列表来解决。
    【解决方案2】:

    我会使用:

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

    如果不想修改dalist,可以先复制,例如dalist2 = dalist 然后修改副本。

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

    dalist[[2 ;;, 2]] = COGCondition /@ dalist[[2 ;;, 4]];
    

    【讨论】:

    • 或者,如果条件以规则列表的形式表示:conditions = {1-> 10, 2-> 20},那么dalist[[2;;, 2]] = dalist[[2 ;;, 4]] /. conditions
    • @Mr.Wizard,非常感谢。如此简单,令人印象深刻。
    • @500,感谢您选择我的解决方案,但我认为这是正确的解决方案。它实现起来更简单,因此没有与基于模式的问题相同的问题。我会使用我的一些想法,比如如何处理默认值,但是这个会让你更快地启动和运行。
    猜你喜欢
    • 2018-04-19
    • 2018-06-16
    • 1970-01-01
    • 2011-09-01
    • 2021-10-25
    • 2011-09-01
    • 1970-01-01
    • 2011-12-22
    • 1970-01-01
    相关资源
    最近更新 更多