How to insert a column into a matrix, the correct Mathematica way

佐手、 提交于 2019-12-02 15:37:45

Your double Transpose method seems fine. For very large matrices, this will be 2-3 times faster:

MapThread[Insert, {a, column, Table[2, {Length[column]}]}]

If you want to mimic your Matlab way, the closest is probably this:

ArrayFlatten[{{a[[All, ;; 1]], Transpose[{column}], a[[All, 2 ;;]]}}]

Keep in mind that insertions require making an entire copy of the matrix. So, if you plan to build a matrix this way, it is more efficient to preallocate the matrix (if you know its size) and do in-place modifications through Part instead.

Bob Jones

You can use Join with a level specification of 2 along with Partition in subsets of size 1:

a = {{1, 2, 3}, {4, 0, 8}, {7 , 8, 0}}
column = {97, 98, 99}
newa = Join[a,Partition[column,1],2]

I think I'd do it the same way, but here are some other ways of doing it:

-With MapIndexed

newa = MapIndexed[Insert[#1, column[[#2[[1]]]], 2] &, a]

-With Sequence:

newa = a;
newa[[All, 1]] = Transpose[{newa[[All, 1]], column}];
newa = Replace[a, List -> Sequence, {3}, Heads -> True]

Interestingly, this would seem to be a method that works 'in place', i.e. it wouldn't really require a matrix copy as stated in Leonid's answer and if you print the resulting matrix it apparently works as a charm.

However, there's a big catch. See the problems with Sequence in the mathgroup discussion "part assigned sequence behavior puzzling".

I usually just do like this:

In: m0 = ConstantArray[0, {3, 4}]; 
    m0[[All, {1, 3, 4}]] = {{1, 2, 3}, {4, 0, 8}, {7, 8, 0}}; 
    m0[[All, 2]] = {97, 98, 99}; m0 

Out: 
    {{1, 97, 2, 3}, {4, 98, 0, 8}, {7, 99, 8, 0}}

I don't know how it compare in terms of efficiency.

tomd

I originally posted this as a comment (now deleted)

Based on a method given by user656058 in this question (Mathematica 'Append To' Function Problem) and the reply of Mr Wizard, the following alternative method of adding a column to a matrix, using Table and Insert, may be gleaned:

(a = {{1, 2, 3}, {4, 0, 8}, {7, 8, 0}});
column = {97, 98, 99};

Table[Insert[a[[i]], column[[i]], 2], {i, 3}] // MatrixForm

giving

Similarly, to add a column of zeros (say):

Table[Insert[#[[i]], 0, 2], {i, Dimensions[#][[1]]}] & @ a 

As noted in the comments above, Janus has drawn attention to the 'trick' of adding a column of zeros by the ArrayFlatten method (see here)

ArrayFlatten[{{Take[#, All, 1], 0, Take[#, All, -2]}}] & @ 
  a // MatrixForm

Edit

Perhaps simpler, at least for smaller matrices

(Insert[a[[#]], column[[#]], 2] & /@ Range[3]) // MatrixForm

or, to insert a column of zeros

Insert[a[[#]], 0, 2] & /@ Range[3]

Or, a little more generally:

Flatten@Insert[a[[#]], {0, 0}, 2] & /@ Range[3] // MatrixForm

May also easily be adapted to work with Append and Prepend, of course.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!