Замена условного списка значений в Mathematica - PullRequest
2 голосов
/ 16 августа 2011

Пожалуйста, примите во внимание:

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

enter image description here

COGCondition1 = 10
COGCondition2 = 20

Я хотел бы заменить значения в столбце «Blah» на значение, принятое в столбце «COGCondition», таким образом:

Если для данной строки значение в столбце «COGCondition» = 1, значение в столбце «Blah» должно быть равно COGCondition1 (А 2 -> COGCondition2)

Желаемый вывод:

enter image description here

Мне это нужно для большого набора данных, и мои попытки использовать Table и Switch не увенчались успехом. Я могу легко генерировать новые столбцы, но не могу понять, как заменить значения, используя Switch.

Ответы [ 2 ]

7 голосов
/ 16 августа 2011

Это довольно просто с правилом замены:

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}

К сожалению, это несколько хрупко, потому что требует немного дополнительной работы, если вы измените количество условий. Метод, предложенный Леонидом, заключался в создании функции

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}

Если вы обнаружите, что у вас есть более 1 столбца между x и y, тогда ваш шаблон просто {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 сверху.

6 голосов
/ 16 августа 2011

Я бы использовал:

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

dalist //TableForm

enter image description here

Если изменение dalist нежелательно, вы можете сначала скопировать его, например, dalist2 = dalist, а затем измените копию.

Особенно, если у вас много значений для столбца условия, я советую вам следовать предыдущей рекомендации использовать индексированную переменную (COGCondition[1]). Это будет выглядеть так:

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