Добавление к строкам таблицы
У меня есть двумерный список и одномерный список. Я хотел бы вставить 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? Я не думаю, что мне нужен цикл, который я использую. Мое решение кажется уродливым.
Ответы
Ответ 1
Например:
[email protected][[email protected], column]
Вы также можете сделать так:
subListAppend = [email protected][[email protected]#1, #2] &;
subListAppend[array, column]
что упрощает работу, если вам нужно часто его использовать. И, конечно, если вы хотите вставить в любое место, кроме только конца, вы можете использовать Insert[]
.
subListInsert = [email protected][[email protected]#1, #2, #3] &;
subListInsert[array, column, 2]
--> {{a, x, 1, 2}, {b, y, 2, 3}, {c, z, 3, 4}}
EDIT: после того, как началось обязательное обсуждение оптимизации скорости, вот некоторые результаты, используя this и массив 10000x200:
[email protected]{{array, List /@ column}}: 0.020 s
[email protected][[email protected], 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[[email protected][{array, column}], 4]: 0.48 s
И победитель ArrayFlatten
!
Ответ 2
Другая возможность -
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), но распакует результат. (Но если у вас есть символические записи, как в примере, это не проблема).
Ответ 3
Вот моя попытка с помощью Join
In[11]:= Join[array,List/@column,2]
Out[11]= {{a,1,2,x},{b,2,3,y},{c,3,4,z}}
Это может быть сопоставимо с самым быстрым из ранее упомянутых программ.
Ответ 4
Как насчет этого?
pos = 4;
MapThread[Insert[#1, #2, pos] &, {array, column}]
Ответ 5
Мне (иногда) нравится транспонировать с помощью 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}}
(Transpose здесь не работает)
Ответ 6
Тем не менее:
k= Partition[[email protected][{#, {x, y, z}}], 4]&
[email protected] {{a, 1, 2}, {b, 2, 3}, {c, 3, 4}}
(*
-> {{a, 1, 2, x}, {b, 2, 3, y}, {c, 3, 4, z}}
*)
Ответ 7
Хотя это не так практично или эффективно, как некоторые из существующих методов, добавьте еще два списка:
ArrayPad[array, {0,{0,1}}, List /@ column]
PadRight[array, Dimensions[array] + {0, 1}, List /@ column]