note.nkmk.me

NumPy配列ndarrayに要素・行・列を挿入、追加するinsertの使い方

Date: 2018-03-11 / tags: Python, NumPy

numpy.insert()関数を使うと、NumPy配列ndarrayに要素や行・列を挿入(追加)することができる。

ここでは、

  • numpy.insert()の概要
  • 一次元配列
    • numpy.insert()で要素を挿入、追加
    • 要素を置換
  • 二次元配列の行
    • numpy.insert()で行を挿入、追加
    • numpy.vstack()で先頭・末尾に行を追加
    • 行を置換
  • 二次元配列の列
    • numpy.insert()で列を挿入、追加
    • numpy.hstack()で先頭・末尾に列を追加
    • 列を置換

について、サンプルコードとともに説明する。

スポンサーリンク

numpy.insert()の概要

np.insert()関数の引数は以下の通り。

  • arr: 元のNumPy配列ndarray
  • obj: valueが挿入される位置、int, slice, list
  • value: 挿入される要素・行・列
  • axis: valueが挿入される軸(次元)

元のNumPy配列ndarrayはそのまま変更されず、新たなndarrayが返される。

numpy.insert()で一次元配列に要素を挿入、追加

一次元配列に要素を挿入する場合、np.insert()の引数axis=None(デフォルト値なので省略可能)とする。

引数valueをリストで指定して、まとめて挿入することもできる。

import numpy as np

a = np.arange(4)
print(a)
# [0 1 2 3]

print(np.insert(a, 2, 100))
# [  0   1 100   2   3]

print(np.insert(a, 1, [100, 101, 102]))
# [  0 100 101 102   1   2   3]

print(np.insert(a, [0, 2, 4], [100, 101, 102]))
# [100   0   1 101   2   3 102]

一次元配列の要素を置換

一次元配列の要素を置換したい場合は以下のように書ける。元のndarrayの値が置換されるので、便宜上コピーを作成し処理している。

_a = a.copy()
_a[1] = 100
print(_a)
# [  0 100   2   3]

_a = a.copy()
_a[1:3] = [100, 101]
print(_a)
# [  0 100 101   3]

置換前と置換後のndarrayの形状が変わるような操作はエラーになる。

np.insert()で挿入したあとでnp.delete()で不要な値を削除すれば所望の配列が得られる。

# _a = a.copy()
# _a[1] = [100, 101, 102]
# print(_a)
# ValueError: setting an array element with a sequence.

_a = np.insert(a, 1, [100, 101, 102])
_a = np.delete(_a, 4)
print(_a)
# [  0 100 101 102   2   3]

numpy.insert()で二次元配列に行を挿入、追加

引数axis=None(デフォルト)とすると、元のndarrayが多次元配列の場合でも平坦化された一次元配列が返される。

a = np.arange(12).reshape((3, 4))
print(a)
# [[ 0  1  2  3]
#  [ 4  5  6  7]
#  [ 8  9 10 11]]

print(np.insert(a, 2, 100))
# [  0   1 100   2   3   4   5   6   7   8   9  10  11]

二次元配列ndarrayに行を挿入したい場合はaxis=0とする。

引数valueにスカラー値を指定すると、その値で埋められた行が挿入される。

print(np.insert(a, 2, 100, axis=0))
# [[  0   1   2   3]
#  [  4   5   6   7]
#  [100 100 100 100]
#  [  8   9  10  11]]

一次元配列ndarrayを挿入

要素数が元のndarrayの列数に等しい一次元配列ndarrayを挿入することができる。

挿入位置を指定する引数objはリスト(配列)でも指定できる。その場合、各行に同じ配列が挿入される。

b1 = np.arange(100, 104)
print(b1)
# [100 101 102 103]

print(np.insert(a, 1, b1, axis=0))
# [[  0   1   2   3]
#  [100 101 102 103]
#  [  4   5   6   7]
#  [  8   9  10  11]]

print(np.insert(a, 3, b1, axis=0))
# [[  0   1   2   3]
#  [  4   5   6   7]
#  [  8   9  10  11]
#  [100 101 102 103]]

print(np.insert(a, [0, 2], b1, axis=0))
# [[100 101 102 103]
#  [  0   1   2   3]
#  [  4   5   6   7]
#  [100 101 102 103]
#  [  8   9  10  11]]

二次元配列ndarrayを挿入

元のndarrayと列数が等しい二次元配列ndarrayを挿入することもできる。

挿入位置を指定する引数objをリスト(配列)で指定した場合、各行がそれぞれの位置に挿入される。

b2 = np.arange(100, 112).reshape((3, 4))
print(b2)
# [[100 101 102 103]
#  [104 105 106 107]
#  [108 109 110 111]]

print(np.insert(a, 2, b2, axis=0))
# [[  0   1   2   3]
#  [  4   5   6   7]
#  [100 101 102 103]
#  [104 105 106 107]
#  [108 109 110 111]
#  [  8   9  10  11]]

print(np.insert(a, 2, b2[2], axis=0))
# [[  0   1   2   3]
#  [  4   5   6   7]
#  [108 109 110 111]
#  [  8   9  10  11]]

print(np.insert(a, [0, 2, 3], b2, axis=0))
# [[100 101 102 103]
#  [  0   1   2   3]
#  [  4   5   6   7]
#  [104 105 106 107]
#  [  8   9  10  11]
#  [108 109 110 111]]

print(np.insert(a, range(3), b2, axis=0))
# [[100 101 102 103]
#  [  0   1   2   3]
#  [104 105 106 107]
#  [  4   5   6   7]
#  [108 109 110 111]
#  [  8   9  10  11]]

numpy.vstack()で二次元配列の先頭・末尾に行を追加

ndarrayの途中ではなく先頭、末尾に行を追加する場合は、np.insert()のほかに、ndarrayを縦に連結するnp.vstack()も使える。

要素数が元のndarrayの列数に等しい一次元配列ndarray、元のndarrayと列数が等しい二次元配列ndarrayのどちらでもOK。

print(np.vstack((a, b1)))
# [[  0   1   2   3]
#  [  4   5   6   7]
#  [  8   9  10  11]
#  [100 101 102 103]]

print(np.vstack((b2, a)))
# [[100 101 102 103]
#  [104 105 106 107]
#  [108 109 110 111]
#  [  0   1   2   3]
#  [  4   5   6   7]
#  [  8   9  10  11]]

二次元配列の行を置換

行を置換したい場合は以下のように書ける。元のndarrayが変更される。

選択される行数が一致していればスライスでもリストでもOK。

_a = a.copy()
_a[2] = b1
print(_a)
# [[  0   1   2   3]
#  [  4   5   6   7]
#  [100 101 102 103]]

_a = a.copy()
_a[1] = b2[1]
print(_a)
# [[  0   1   2   3]
#  [104 105 106 107]
#  [  8   9  10  11]]

_a = a.copy()
_a[1:] = b2[[0, 2]]
print(_a)
# [[  0   1   2   3]
#  [100 101 102 103]
#  [108 109 110 111]]

一次元配列の場合と同様に、形状(行数)が変わる操作はエラーになるので、np.insert()で挿入したあとでnp.delete()で不要な行を削除する。

numpy.insert()で二次元配列に列を挿入、追加

二次元配列ndarrayに列を挿入したい場合はaxis=1とする。基本的には行の場合と同じ要領。

print(a)
# [[ 0  1  2  3]
#  [ 4  5  6  7]
#  [ 8  9 10 11]]

print(np.insert(a, 1, 100, axis=1))
# [[  0 100   1   2   3]
#  [  4 100   5   6   7]
#  [  8 100   9  10  11]]

c1 = np.arange(100, 103)
print(c1)
# [100 101 102]

print(np.insert(a, 1, c1, axis=1))
# [[  0 100   1   2   3]
#  [  4 101   5   6   7]
#  [  8 102   9  10  11]]

print(np.insert(a, 3, c1, axis=1))
# [[  0   1   2 100   3]
#  [  4   5   6 101   7]
#  [  8   9  10 102  11]]

二次元配列ndarrayを挿入する場合は、挿入位置を指定する引数objに注意が必要。

objをスカラー値で指定したい場合、xではなく[x]としないとエラーとなる。

c2 = np.arange(100, 106).reshape((3, 2))
print(c2)
# [[100 101]
#  [102 103]
#  [104 105]]

# print(np.insert(a, 1, c2, axis=1))
# ValueError: could not broadcast input array from shape (2,3) into shape (3,3)

print(np.insert(a, [1], c2, axis=1))
# [[  0 100 101   1   2   3]
#  [  4 102 103   5   6   7]
#  [  8 104 105   9  10  11]]

print(np.insert(a, [0, 2], c2, axis=1))
# [[100   0   1 101   2   3]
#  [102   4   5 103   6   7]
#  [104   8   9 105  10  11]]

一列だけを挿入する場合も、一次元配列を挿入するか二次元配列を挿入するかによって出力が異なる。詳細はここでは触れないが、ブロードキャストの規則に従った結果である。

一次元配列を挿入する際に引数obj[x]としたりリスト(配列)で複数位置を指定したりすると想定と異なる結果になる。

print(c1)
# [100 101 102]

print(np.insert(a, 1, c1, axis=1))
# [[  0 100   1   2   3]
#  [  4 101   5   6   7]
#  [  8 102   9  10  11]]

print(np.insert(a, [1], c1, axis=1))
# [[  0 100 101 102   1   2   3]
#  [  4 100 101 102   5   6   7]
#  [  8 100 101 102   9  10  11]]

print(np.insert(a, [1, 3, 4], c1, axis=1))
# [[  0 100   1   2 101   3 102]
#  [  4 100   5   6 101   7 102]
#  [  8 100   9  10 101  11 102]]

_c1 = c1.reshape((3, 1))
print(_c1)
# [[100]
#  [101]
#  [102]]

print(np.insert(a, 1, _c1, axis=1))
# [[  0 100 101 102   1   2   3]
#  [  4 100 101 102   5   6   7]
#  [  8 100 101 102   9  10  11]]

print(np.insert(a, [1], _c1, axis=1))
# [[  0 100   1   2   3]
#  [  4 101   5   6   7]
#  [  8 102   9  10  11]]

print(np.insert(a, [1, 3, 4], _c1, axis=1))
# [[  0 100   1   2 100   3 100]
#  [  4 101   5   6 101   7 101]
#  [  8 102   9  10 102  11 102]]

numpy.hstack()で二次元配列の先頭・末尾に列を追加

ndarrayの途中ではなく先頭、末尾に列を追加する場合は、np.insert()のほかに、ndarrayを横に連結するnp.hstack()も使える。

元のndarrayと追加するndarrayの次元数が一致していないとエラーになるので注意。一列だけの場合もreshape()メソッドで二次元配列に変換する必要がある。

# print(np.hstack((a, c1)))
# ValueError: all the input arrays must have same number of dimensions

print(_c1)
# [[100]
#  [101]
#  [102]]

print(np.hstack((a, _c1)))
# [[  0   1   2   3 100]
#  [  4   5   6   7 101]
#  [  8   9  10  11 102]]

print(np.hstack((_c1, a)))
# [[100   0   1   2   3]
#  [101   4   5   6   7]
#  [102   8   9  10  11]]

print(np.hstack((a, c2)))
# [[  0   1   2   3 100 101]
#  [  4   5   6   7 102 103]
#  [  8   9  10  11 104 105]]

print(np.hstack((c2, a)))
# [[100 101   0   1   2   3]
#  [102 103   4   5   6   7]
#  [104 105   8   9  10  11]]

二次元配列の列を置換

列を置換したい場合は以下のように書ける。元のndarrayが変更される。

選択される列数が一致していればスライスでもリストでもOK。

_a = a.copy()
_a[:, 1] = c1
print(_a)
# [[  0 100   2   3]
#  [  4 101   6   7]
#  [  8 102  10  11]]

_a = a.copy()
_a[:, :2] = c2
print(_a)
# [[100 101   2   3]
#  [102 103   6   7]
#  [104 105  10  11]]

_a = a.copy()
_a[:, [0, 3]] = c2
print(_a)
# [[100   1   2 101]
#  [102   5   6 103]
#  [104   9  10 105]]

これまでの例と同様に、形状(列数)が変わる操作はエラーになるので、np.insert()で挿入したあとでnp.delete()で不要な行を削除する。

スポンサーリンク
シェア
このエントリーをはてなブックマークに追加

関連カテゴリー

関連記事