NumPy

NumPy Quickstart チュートリアルに取り組む (5-2) ブール型配列を使ったインデックス作成

インデックスの配列で配列のインデックスを作成する際には、取り出すインデックスのリストを提供している。

ブール値インデックスの最も自然な方法は、元の配列と同じ形状のブール値配列を使うこと。

import numpy as np
a = np.arange(12).reshape(3,4)
b = a > 4
print(b)                                          # bはaの形状を持つブール値
'''
[[False False False False]
 [False  True  True  True]
 [ True  True  True  True]]
'''


print(a[b])                                       # 選択された要素を持つ1次元配列
# [ 5  6  7  8  9 10 11]

このプロパティは割当に役立つ。

a[b] = 0                                   # 4より大きい'a'のすべての要素が0になる
print(a)
'''
[[ 0 1 2 3 ]
 [ 4 0 0 0 ]
 [ 0 0 0 0 ]]
'''

マンデルブロ集合のイメージを生成するためにブーリアンインデックスを使用する例。

import numpy as np
import matplotlib.pyplot as plt
def mandelbrot( h,w, maxit=20 ):
    """サイズ(h,w)のマンデルブロフラクタルの画像を返す"""
    y,x = np.ogrid[ -1.4:1.4:h*1j, -2:0.8:w*1j ]
    c = x+y*1j
    z = c
    divtime = maxit + np.zeros(z.shape, dtype=int)

    for i in range(maxit):
        z = z**2 + c
        diverge = z*np.conj(z) > 2**2            # どっちがどっちか
        div_now = diverge & (divtime==maxit)  # どっちがどっちか
        divtime[div_now] = i                  # 記録
        z[diverge] = 2                        #  乖離を避ける

    return divtime
plt.imshow(mandelbrot(400,400))

ブール値を用いたインデックス作成の2番目の方法は、整数インデックス作成に似ており、配列の各次元に対して、スライスを選択する1次元のブール値配列を与える。

import numpy as np
a = np.arange(12).reshape(3,4)
b1 = np.array([False,True,True])             # 最初の次元
b2 = np.array([True,False,True,False])       # 2番目の次元

print(a[b1,:])                                   # 行選択
'''
[[ 4  5  6  7]
 [ 8  9 10 11]]
'''

print(a[b1])                                    # 同じ意味
'''
[[ 4  5  6  7]
 [ 8  9 10 11]]
'''

print(a[:,b2])                                   # 列選択
'''
[[ 0  2]
 [ 4  6]
 [ 8 10]]
'''

print(a[b1,b2])                                  # 変わった表現
# [ 4 10]

1次元ブーリアン配列の長さは、スライスしたい次元(または軸)の長さと一致しなければならないことに注意が必要。前の例では、b1は長さ3(aの行の数)で、b2(長さ4)はaの2番目の軸(列)をインデックスするのに適している。