numpy.insert()
numpy.insert() は指定した位置に配列や数値を挿入する関数です。
numpy.insert(arr, obj, values, axis=None)
arr に配列、obj にインデックス、values に挿入する値を渡します。
最初に簡単な例として、一次元配列に数値を挿入してみます。
# NUMPY_INSERT # In[1] import numpy as np # [1 2 3 4 5] x = np.arange(1, 6) # インデクス2の位置に0を挿入 a = np.insert(x, 2, 0) print(a) # [1 2 0 3 4 5]
複数のインデクスを指定して挿入することもできます。
# In[2] # インデクス1とインデクス3の位置に0を挿入 b = np.insert(x, [1, 3], 0) print(b) # [1 0 2 3 0 4 5]
arr が二次元配列のときに、axis を指定しないと一次元配列にフラット化されます。
# In[3] # [[1 2] # [3 4] # [5 6]] y = np.arange(1, 7).reshape(3, 2) # yを1次元にフラット化して、インデクス4の位置に0を挿入 c = np.insert(y, 4, 0) print(c) # [1 2 3 4 0 5 6]
axis=0 を指定すると、ブロードキャストが適用されて (配列サイズに合うように引き伸ばされて) 行に挿入されます。
# In[4] # yの2行目に0を挿入 d = np.insert(y, 1, 0, axis=0) print(d) # [[1 2] # [0 0] # [3 4] # [5 6]]
axis=1 を指定すると、縦に引き伸ばされて列に挿入されます。
# In[5] # yの2列目に0を挿入 e = np.insert(y, 1, 0, axis=1) print(e) # [[1 0 2] # [3 0 4] # [5 0 6]]
二次元配列に一次元配列を挿入する場合も、適切なサイズに変更されてから挿入が実行されます。
# In[6] # yの2列目に[0,9]を挿入 f = np.insert(y, 1, [[0], [9]], axis=1) print(f) # [[1 0 9 2] # [3 0 9 4] # [5 0 9 6]]
次のコードは二次元配列の中に二次元配列を挿入します。
# In[7] # 2次元配列を定義 z = np.array([[0, 0], [9, 9]]) # yの2行目にzを挿入 g = np.insert(y, 1, z, axis=0) print(g) # [[1 2] # [0 0] # [9 9] # [3 4] # [5 6]]
上のコードで obj に複数インデクスを渡すと、values に渡した配列は行ごとに分解されます。
# In[8] # yの1行目にzの1行目を、yの3行目にzの2行目を挿入 h = np.insert(y, [0, 2], z, axis=0) print(h) # [[0 0] # [1 2] # [3 4] # [9 9] # [5 6]]
最後に arr に三次元配列を渡す例を見てみます。
# In[9] # 3次元配列を定義 w = np.array([[[1, 2],[ 3, 4]], [[5, 6],[ 7, 8]], [[9, 10],[11, 12]]]) print(w) # [[[ 1 2] # [ 3 4]] # [[ 5 6] # [ 7 8]] # [[ 9 10] # [11 12]]]
配列 w に 0 を埋め込んでみます。
axis は 0, 1, 2 の 3 種類を指定できます。
axis=2 を指定した場合は次のような結果となります。
# In[10] # wの第2軸に0を挿入 i = np.insert(w, 2, 0, axis=2) print(i) # [[[ 1 2 0] # [ 3 4 0]] # [[ 5 6 0] # [ 7 8 0]] # [[ 9 10 0] # [11 12 0]]]
コメント
In[7] プログラムを参考にして、2 次元配列の列に 2 次元配列を挿入しようと思って z として (3, 2) 配列を作成して、axis=1 を指定して実行したら下記のエラーが出ました。
—————————————————————————————-
z = np.array([[0, 0],
[9, 9],
[3, 3]])
# yの2列目にzを挿入
g = np.insert(y, 1, z, axis=1)
print(g)
—————————————————————————————-
ValueError: could not broadcast input array from shape (2,3) into shape (3,3)
エラーメッセージの意味が理解できなくて少し焦りましたが、結局インデックスを [1] のように [ ] で囲う必要があったようです。この辺の事情を解説していただけるとありがたいです。
NumPy のタイトルページで「要素を置換:numpy.where( )」のリンク先が numpy.place( ) になっています。numpy.where( ) → numpy.place( ) に修正するとわかりやすいと思いましたが、ご確認ください。
以下のコードを試してみてください。
np.insert() の第 2 引数に 1 を指定した場合、配列 a の各行に配列 b の列成分が挿入されています。次に第 2 引数に [1] を渡してみます。
今度は配列 a の各行に配列 b の行成分が挿入されています。それで、ご質問にあったコードを実行した際に内部でどのような処理がされるのかを考えてみます。
配列 y の各行に配列 z の列成分を挿入しようとすると、
[[1 0 0 0 2],
[3 9 9 9 4],
[5 ……… 6]]
のようになって成分が足りなくなってしまいます。エラーメッセージに「(2, 3) の形の配列を (3, 3) の形にブロードキャストできない」とありましたが、以下のように z をブロードキャストできる形で渡せばエラーになりません。
NumPy のタイトルページのリンクを修正させていただきました。ありがとうございます。m(_ _)m
ご回答ありがとうございました。
エラーの意味がよくわかり、マニュアルも読めるようになりました。
「インデックスがスカラーの場合はルールに従って配列を組み替えて挿入するが、インデックスをシーケンスで指定された場合は、与えられた配列のシーケンスは壊さないで挿入する」という理解で行こうと思います。
ChatGPTにnumpy.insertを会話形式で解説してもらいました
生徒: こんにちは、講師さん!NumPyのinsert関数について教えていただけますか?insert関数はappend関数と似ているのでしょうか?
講師: こんにちは!insert関数は、append関数とは異なる動作をする関数です。insert関数は、NumPy配列の指定された位置に要素を挿入するための関数です。append関数は末尾に要素を追加するのに対して、insert関数は任意の位置に要素を挿入します。
生徒: なるほど、insert関数は指定した位置に要素を挿入するんですね。具体的な使い方を教えていただけますか?
講師: もちろんです。insert関数は、3つの引数を受け取ります。1つ目の引数は対象の配列であり、2つ目の引数は挿入したい位置を示すインデックスです。3つ目の引数は挿入する要素です。
この例では、arrayという既存の配列に要素1, 2, 3, 4が含まれています。そして、insert_indexという変数でインデックス2(3番目)の位置に要素99を挿入しています。
生徒: なるほど、結果はどうなるんですか?
講師: 挿入後の結果はnew_arrayという新しい配列として表示されます。new_arrayを出力すると、[1, 2, 99, 3, 4]という配列が得られます。
生徒: なるほど、理解しました!insert関数は指定した位置に要素を挿入するためのものですね。他にも何か重要なポイントはありますか?
講師: はい、注意点としては、insert関数もappend関数と同様に新しい配列を作成するため、元の配列は変更されないということです。また、指定するインデックスは挿入前の配列のインデックスであり、挿入後のインデックスではありませんので、注意が必要です。