Присоединение к строкам таблицы
У меня есть двухмерный список и одномерный список. Я хотел бы вставить список 1D в список 2D в качестве дополнительного столбца. Например:
array = {{a,1,2},{b,2,3},{c,3,4}};
column = {x,y,z};
становится
final = {{a,1,2,x},{b,2,3,y},{c,3,4,z}};
Я сделал это неуверенно:
Table[Insert[array[[i]], column[[i]], 4], {i, Length[array]}];
Мой вопрос: как правильно сделать это в Mathematica? Я не думаю, что это нуждается в цикле, который я использую. Мое решение кажется уродливым.
7 ответов
Например:
Transpose@Append[Transpose@array, column]
Вы также можете сделать такую функцию:
subListAppend = Transpose@Append[Transpose@#1, #2] &;
subListAppend[array, column]
что облегчает, если вам приходится часто его использовать. И, конечно, если вы хотите вставить в любое место, кроме конца, который вы можете использовать Insert[]
,
subListInsert = Transpose@Insert[Transpose@#1, #2, #3] &;
subListInsert[array, column, 2]
--> {{a, x, 1, 2}, {b, y, 2, 3}, {c, z, 3, 4}}
РЕДАКТИРОВАТЬ: Поскольку обсуждение обязательной оптимизации скорости началось, вот некоторые результаты с использованием этого и массива 10000x200:
ArrayFlatten@{{array, List /@ column}}: 0.020 s
Transpose@Append[Transpose@array, column]: 0.067 s
MapThread[Append, {array, column}]: 0.083 s
MapThread[Insert[#1, #2, 4] &, {array, column}]: 0.095 s
Map[Flatten, Flatten[{array, column}, {2}]]: 0.26 s
ConstantArray based solution: 0.29 s
Partition[Flatten@Transpose[{array, column}], 4]: 0.48 s
И победитель ArrayFlatten
!
Вот моя попытка с помощью Join
In[11]:= Join[array,List/@column,2]
Out[11]= {{a,1,2,x},{b,2,3,y},{c,3,4,z}}
Это может быть сравнимо с самой быстрой среди ранее упомянутых программ.
Другая возможность
result = ConstantArray[0, Dimensions[array] + {0, 1}];
result[[All, 1 ;; Last[Dimensions[array]]]] = array;
result[[All, -1]] = column;
что, кажется, быстрее на моем компьютере для больших числовых матриц, хотя требует дополнительной переменной. Если вы имеете дело с реальными записями, вы захотите использовать
result = ConstantArray[0.0, Dimensions[array] + {0, 1}];
чтобы сохранить прирост скорости.
Есть также
MapThread[Append, {array, column}]
который также быстрый (и элегантный IMO), но распакует результат. (Но если у вас есть символические записи, как в примере, это не проблема.)
Как насчет этого?
pos = 4;
MapThread[Insert[#1, #2, pos] &, {array, column}]
Мне (иногда) нравится транспонировать с Flatten, так как он работает с "рваным" массивом.
Map[Flatten, Flatten[{array, column}, {2}]]
дающий
{{a, 1, 2, x}, {b, 2, 3, y}, {c, 3, 4, z}}
Но если, скажем, столбец имеет только 2 элемента
column2 = {x, y};
Map[Flatten, Flatten[{array, column2}, {2}]]
дающий
{{a, 1, 2, x}, {b, 2, 3, y}, {c, 3, 4}}
(Транспонировать здесь не получится)
Еще:
k= Partition[Flatten@Transpose[{#, {x, y, z}}], 4]&
k@ {{a, 1, 2}, {b, 2, 3}, {c, 3, 4}}
(*
-> {{a, 1, 2, x}, {b, 2, 3, y}, {c, 3, 4, z}}
*)
Хотя это не так практично или эффективно, как некоторые из существующих методов, вот еще два, чтобы добавить в список:
ArrayPad[array, {0,{0,1}}, List /@ column]
PadRight[array, Dimensions[array] + {0, 1}, List /@ column]