NumPy配列のスライス表記の参照と代入

NumPyのndarrayは、[a:b] というような表記で範囲を指定して参照することができる。 [] の中をコロンで区切って、開始インデックスと終了インデックスを書く。終了インデックスの直前までになる。

これをスライス表記だとかスライシングなどという。

このスライス表記はPythonの通常のリストにもある仕組みだが、NumPyのndarrayが違う点は、代入もできることである。スライス表記に代入すると、もとのndarrayの一部をまとめて書き換えることができる。

ndarr1 = np.array([0, 1, 2, 3, 4, 5])

print(ndarr1[1:3])
# 出力結果
# [1 2]

# スライス表記に同じ大きさの配列を代入すれば、それがそのままその位置に代入される
ndarr1[3:6] = [100., 200., 300.]
print(ndarr1)
# 出力結果
# [  0   1   2 100 200 300]

スライス表記に配列ではなく数値を代入すると、そのスライスの範囲にある要素すべてに同一の値が代入される。これをブロードキャストという。

# スライス表記に数値を代入すると、スライスの範囲全部が同じ値になる
ndarr1[3:5] = 20
print(ndarr1)
# 出力結果
# [ 0  1  2 20 20  5]

スライシングしたものを別の変数に入れると、そのスライスはビューになり、スライスを通してもとのndarrayを変更することができるようになる。

ndarr1 = np.array([0, 1, 2, 3, 4, 5])

sl = ndarr1[3:6]

print(sl)
# 出力結果
# [3 4 5]

sl[0] = 100

print(sl)
# 出力結果
# [100   4   5]

print(ndarr1)
# 出力結果
# [  0   1   2 100   4   5]

sl[:] = 200

print(sl)
# 出力結果
# [200 200 200]

print(ndarr1)
# 出力結果
# [  0   1   2 200 200 200]

スライスのビューではなく、別の実体としたい場合には copy() メソッドを使う。

ndarr1 = np.array([0, 1, 2, 3, 4, 5])

sl = ndarr1[3:6].copy()

print(sl)

sl[0] = 100
print(sl)
# 出力結果
# [100   4   5]

# もとのndarrayには影響せず
print(ndarr1)
# 出力結果
# [0 1 2 3 4 5]

多次元の場合は [] の中にコンマ区切りで範囲指定を記述する。

ndarr1 = np.array([[1., 2., 3.], [4., 5., 6.], [7., 8., 9.]])

print(ndarr1)
# 出力結果
# [[ 1.  2.  3.]
#  [ 4.  5.  6.]
#  [ 7.  8.  9.]]

print(ndarr1[1:3])
# 出力結果
# [[ 4.  5.  6.]
#  [ 7.  8.  9.]]

print(ndarr1[1:3, 0:2])
# 出力結果
# [[ 4.  5.]
#  [ 7.  8.]]

範囲指定を : だけにすると全体範囲の意味になり、以下の例では結果的に内側の軸のみ範囲指定している。

print(ndarr1[:, 0:2])
# 出力結果
# [[ 1.  2.]
#  [ 4.  5.]
#  [ 7.  8.]]
このサイトは筆者(hydrocul)の個人メモの集合です。すべてのページは永遠に未完成です。