NumPy:インデックスとスライス
配列の一部を取り出したり書き換えたりする操作をまとめる. セルオートマトン(P2-02)や拡散方程式(P2-03)では,注目するセルとその近傍を取り出すためにこれらを多用する.
import numpy as np
a = np.array([1, 2, 3])
b = np.array([6, 3.3, 1])
C = np.array([[1, 5, 6], [7, 8, 9], [4, 2, 3]])
D = np.array([[2.3, 4, 7.2], [7, 9, 1], [11, 2, 9]])インデックス¶
位置(インデックス)を指定して1つの要素にアクセスする.インデックスは 0 から始まる.負の値は末尾から数える.
print("a[0]:", a[0])
print("末尾 a[-1]:", a[-1])a[0]: 1
末尾 a[-1]: 3
2次元配列では,行・列の順にインデックスを与える.C[0] は0行目全体,C[0, 1] は0行1列の要素である.
print("0行目 C[0]:", C[0])
print("0行1列 C[0, 1]:", C[0, 1])0行目 C[0]: [1 5 6]
0行1列 C[0, 1]: 5
スライス¶
スライス (slicing)は,start:stop:step の形で連続した範囲を取り出す操作である.stop は含まれない点に注意する.
print("b[0:2]:", b[0:2]) # 0 番目から 2 未満
print("b[::2]:", b[::2]) # 1 つおきb[0:2]: [6. 3.3]
b[::2]: [6. 1.]
2次元配列では行と列それぞれにスライスを与えられる.
print("D の左上 2x2 ブロック:\n", D[0:2, 0:2])
print("0 列目全体 D[:, 0]:", D[:, 0])D の左上 2x2 ブロック:
[[2.3 4. ]
[7. 9. ]]
0 列目全体 D[:, 0]: [ 2.3 7. 11. ]
ファンシーインデックス¶
ファンシーインデックス (fancy indexing)では,整数のリストを添字に渡して任意の行や列をまとめて選べる.
print("0,1 行目:\n", C[[0, 1]])
print("0,1 列目:\n", C[:, [0, 1]])0,1 行目:
[[1 5 6]
[7 8 9]]
0,1 列目:
[[1 5]
[7 8]
[4 2]]
行と列の両方をリストで指定する場合は,2段階に分けて書くと分かりやすい.
# 0,1 行かつ 0,1 列のブロック
print(C[[0, 1]][:, [0, 1]])[[1 5]
[7 8]]
ブールインデックス(条件による選択)¶
ブールインデックス (boolean indexing)では,真偽値の配列でマスクして条件を満たす要素だけを取り出せる.
print("C > 5:\n", C > 5)
print("5 より大きい要素:", C[C > 5])
# 条件を満たす要素だけ書き換える
C2 = np.copy(C)
C2[C2 > 5] = 0
print("5 超を 0 に:\n", C2)C > 5:
[[False False True]
[ True True True]
[False False False]]
5 より大きい要素: [6 7 8 9]
5 超を 0 に:
[[1 5 0]
[0 0 0]
[4 2 3]]
近傍の取り出し(応用)¶
セルオートマトンや拡散方程式では,あるセル [i, j] とその上下左右・周囲のセルをまとめて取り出す.
ファンシーインデックスを使うと,端で反対側に回り込む周期境界条件 (periodic boundary condition)を簡潔に表現できる.
field = np.arange(16).reshape(4, 4)
print("field:\n", field)
# 中心 i=0, j=0 の 3x3 近傍(-1 で末尾に回り込む = 周期境界)
i, j = 0, 0
neighborhood = field[[i - 1, i, i + 1], :][:, [j - 1, j, j + 1]]
print("(0,0) の周期的 3x3 近傍:\n", neighborhood)field:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]]
(0,0) の周期的 3x3 近傍:
[[15 12 13]
[ 3 0 1]
[ 7 4 5]]
field[[i-1, i, i+1], :] でまず3行を選び,続く [:, [j-1, j, j+1]] で3列を選ぶ.
i-1 が -1 になると末尾の行を指すため,格子の端がトーラス状につながる.この考え方を P2-02・P2-03 で繰り返し使う.