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

前端 未结 5 1397
旧时难觅i
旧时难觅i 2021-01-30 14:40

I think Mathematica is biased towards rows not columns.

Given a matrix, to insert a row seems to be easy, just use Insert[]

(a = {{1, 2, 3},         


        
相关标签:
5条回答
  • 2021-01-30 15:02

    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.

    0 讨论(0)
  • 2021-01-30 15:05

    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

    enter image description here

    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.

    0 讨论(0)
  • 2021-01-30 15:08

    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".

    0 讨论(0)
  • 2021-01-30 15:15

    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]
    
    0 讨论(0)
  • 2021-01-30 15:23

    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.

    0 讨论(0)
提交回复
热议问题