Присоединение к строкам таблицы - PullRequest
13 голосов
/ 24 ноября 2010

У меня есть двумерный список и одномерный список.Я хотел бы вставить список 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 ]

14 голосов
/ 24 ноября 2010

Например:

 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!

5 голосов
/ 13 октября 2011

Вот моя попытка использования Join

In[11]:= Join[array,List/@column,2]
Out[11]= {{a,1,2,x},{b,2,3,y},{c,3,4,z}}

Может быть сравнимо с самой быстрой среди ранее упомянутых программ.

5 голосов
/ 24 ноября 2010

Другая возможность -

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 голосов
/ 25 ноября 2010

Мне (иногда) нравится транспонировать с 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}]]

1011 * дает *

{{a, 1, 2, x}, {b, 2, 3, y}, {c, 3, 4}}

(Транспонирование здесь не будет работать)

3 голосов
/ 25 ноября 2010

Как насчет этого?

pos = 4;
MapThread[Insert[#1, #2, pos] &, {array, column}]
2 голосов
/ 25 ноября 2010

Все еще:

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}}
*)
1 голос
/ 14 октября 2011

Хотя это не так практично или эффективно, как некоторые из существующих методов, вот еще два, чтобы добавить в список:

ArrayPad[array, {0,{0,1}}, List /@ column]

PadRight[array, Dimensions[array] + {0, 1}, List /@ column]
...