NumPy配列のスライス表記の参照と代入 2015/04/20
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.]]