Mathematicaは列ではなく行に偏っていると思います。
行列が与えられた場合、行を挿入するのは簡単なようです。Insert[]
を使用するだけです。
(a = {{1, 2, 3}, {4, 0, 8}, {7 , 8, 0}}) // MatrixForm
1 2 3
4 0 8
7 8 0
row = {97, 98, 99};
(newa = Insert[a, row, 2]) // MatrixForm
1 2 3
97 98 99
4 0 8
7 8 0
しかし、列を挿入するために、いくつかの苦労の末、私は2つの方法を見つけました、以下に示します、そしてここの専門家にもっと短くてより直接的な方法を見ているかどうか尋ねたいと思います(Mathematicaには非常に多くのコマンドがあり、私はそれを見落としていたかもしれません私が今持っている方法はまだそのような基本的な操作には複雑すぎると思うので、この種のことを非常に直接的な方法で行います)。
二重転置を行う必要があります:
a = {{1, 2, 3}, {4, 0, 8}, {7 , 8, 0}}
column = {97, 98, 99}
newa = Transpose[Insert[Transpose[a], column, 2]]
1 97 2 3
4 98 0 8
7 99 8 0
SparseArrayを使用しますが、インデックスの場所に注意する必要があります。これを行うのはちょっと厄介です:
(SparseArray[{{i_, j_} :> column[[i]] /; j == 2, {i_, j_} :> a[[i, j]] /; j == 1,
{i_, j_} :> a[[i, j - 1]] /; j > 1}, {3, 4}]) // Normal
1 97 2 3
4 98 0 8
7 99 8 0
問題は、上記より少し短い、より機能的な方法はありますか?もちろん、上記のいずれかを使用して、使いやすくするためにinsertColumn[...]
などの関数で全体をラップすることもできます。しかし、私が持っているよりもこれを行う簡単な方法があるかどうかを見たかったのです。
参考までに、これは私がMatlabでこれを行う方法です。
EDU>> A=[1 2 3;4 0 8;7 8 0]
A =
1 2 3
4 0 8
7 8 0
EDU>> column=[97 98 99]';
EDU>> B=[A(:,1) column A(:,2:end)]
B =
1 97 2 3
4 98 0 8
7 99 8 0
Double Transpose
メソッドは問題ないようです。非常に大きな行列の場合、これは2〜3倍高速になります。
MapThread[Insert, {a, column, Table[2, {Length[column]}]}]
Matlabの方法を模倣したい場合、最も近いのはおそらくこれです:
ArrayFlatten[{{a[[All, ;; 1]], Transpose[{column}], a[[All, 2 ;;]]}}]
挿入には、マトリックスのコピー全体を作成する必要があることに注意してください。したがって、この方法でマトリックスを作成する場合は、マトリックスを事前に割り当て(サイズがわかっている場合)、代わりにPart
を使用してインプレース変更を行う方が効率的です。
サイズ1のサブセットのパーティションとともに、レベル指定が2の結合を使用できます。
a = {{1, 2, 3}, {4, 0, 8}, {7 , 8, 0}}
column = {97, 98, 99}
newa = Join[a,Partition[column,1],2]
私はそれを同じ方法で行うと思いますが、これを行う他のいくつかの方法があります:
-MapIndexed
を使用
newa = MapIndexed[Insert[#1, column[[#2[[1]]]], 2] &, a]
-Sequence
を使用:
newa = a;
newa[[All, 1]] = Transpose[{newa[[All, 1]], column}];
newa = Replace[a, List -> Sequence, {3}, Heads -> True]
興味深いことに、これは「その場で」機能する方法のように見えます。つまり、Leonidの回答に記載されているように、実際にはマトリックスコピーを必要とせず、結果のマトリックスを印刷すると、明らかに魅力として機能します。
ただし、大きなキャッチがあります。 mathgroupのディスカッション " 部分的に割り当てられたシーケンス動作が不可解 "のSequence
の問題を参照してください。
私は通常このようにします:
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}}
効率の点でどのように比較されるのかわかりません。
私はもともとコメントとしてこれを投稿しました(現在は削除されています)
user656058 in this question(Mathematica'AppendTo)で指定されたメソッドに基づく'関数の問題)および reply of Mr Wizard 、次の追加方法Table
およびInsert
を使用して、行列への列を収集できます。
(a = {{1, 2, 3}, {4, 0, 8}, {7, 8, 0}});
column = {97, 98, 99};
Table[Insert[a[[i]], column[[i]], 2], {i, 3}] // MatrixForm
与える
同様に、ゼロの列を追加するには(たとえば):
Table[Insert[#[[i]], 0, 2], {i, Dimensions[#][[1]]}] & @ a
上記のコメントに記載されているように、 Janus は、ArrayFlatten
メソッドによってゼロの列を追加する「トリック」に注目を集めています( を参照)。 /ここに )
ArrayFlatten[{{Take[#, All, 1], 0, Take[#, All, -2]}}] & @
a // MatrixForm
編集
少なくとも小さな行列の場合は、おそらくもっと単純です
(Insert[a[[#]], column[[#]], 2] & /@ Range[3]) // MatrixForm
または、ゼロの列を挿入します
Insert[a[[#]], 0, 2] & /@ Range[3]
または、もう少し一般的に:
Flatten@Insert[a[[#]], {0, 0}, 2] & /@ Range[3] // MatrixForm
もちろん、Append
およびPrepend
で動作するように簡単に適合させることもできます。