『Python数値計算ノート』ではアフィリエイトプログラムを利用して商品を紹介しています。

numpy.insert

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]]]

コメント

  1. HNaito より:

    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( ) に修正するとわかりやすいと思いましたが、ご確認ください。

    • あとりえこばと より:

      以下のコードを試してみてください。

      a = np.array([[10, 20],
              [30, 40]])
      b = np.array([[0, 1],
              [2, 3]])
      c = np.insert(a, 1, b, axis=1)
      print(c)
      # [[10  0  2 20]
      # [30  1  3 40]]


      np.insert() の第 2 引数に 1 を指定した場合、配列 a の各行に配列 b の列成分が挿入されています。次に第 2 引数に [1] を渡してみます。

      # aの1列目にbを挿入
      d = np.insert(a, [1], b, axis=1)
      print(d)
      # [[10  0  1 20]
      # [30  2  3 40]]


      今度は配列 a の各行に配列 b の行成分が挿入されています。それで、ご質問にあったコードを実行した際に内部でどのような処理がされるのかを考えてみます。

      y = np.array([[1, 2],
              [3, 4],
              [5, 6]])
      z = np.array([[0, 9],
              [0, 9],
              [0, 9]])
      # yの2列目にzを挿入
      g = np.insert(y, 1, z, axis=1)
      print(g)


      配列 y の各行に配列 z の列成分を挿入しようとすると、
      [[1 0 0 0 2],
       [3 9 9 9 4],
       [5 ……… 6]]
      のようになって成分が足りなくなってしまいます。エラーメッセージに「(2, 3) の形の配列を (3, 3) の形にブロードキャストできない」とありましたが、以下のように z をブロードキャストできる形で渡せばエラーになりません。

      y = np.array([[1, 2],
              [3, 4],
              [5, 6]])
      z = np.array([[0], [9]])
      # yの2列目にzを挿入
      g = np.insert(y, 1, z, axis=1)
      print(g)
      # [[1 0 9 2]
      # [3 0 9 4]
      # [5 0 9 6]]


      NumPy のタイトルページのリンクを修正させていただきました。ありがとうございます。m(_ _)m

      • HNaito より:

        ご回答ありがとうございました。
        エラーの意味がよくわかり、マニュアルも読めるようになりました。
        「インデックスがスカラーの場合はルールに従って配列を組み替えて挿入するが、インデックスをシーケンスで指定された場合は、与えられた配列のシーケンスは壊さないで挿入する」という理解で行こうと思います。