NumPy配列ndarrayの条件を満たす要素数をカウント
NumPy配列ndarray
の条件を満たす要素数をカウントする方法について説明する。
条件を満たす要素数ではなく、配列のサイズ(全要素数)はsize
属性で取得できる。
条件を満たす要素・行・列の抽出や削除、置換については以下の記事を参照。
本記事のサンプルコードのNumPyのバージョンは以下の通り。バージョンによって仕様が異なる可能性があるので注意。
import numpy as np
print(np.__version__)
# 1.26.1
ndarrayの条件を満たす要素数をカウント: np.count_nonzero()
np.count_nonzero()
は配列ndarray
の0でない要素の個数をカウントして返す。
a = np.arange(12).reshape((3, 4))
print(a)
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
print(np.count_nonzero(a))
# 11
ndarray
をスカラー値と比較すると、bool
値(True
, False
)を要素とするndarray
が返される。<
や==
, !=
などで比較できる。
print(a < 4)
# [[ True True True True]
# [False False False False]
# [False False False False]]
print(a % 2 == 0)
# [[ True False True False]
# [ True False True False]
# [ True False True False]]
True
は1
, False
は0
とみなされるので、これらのndarray
をnp.count_nonzero()
に渡すと、True
の数、すなわち、条件を満たす要素の個数が得られる。
print(np.count_nonzero(a < 4))
# 4
print(np.count_nonzero(a % 2 == 0))
# 6
np.sum()
でも同じ結果となるが、np.count_nonzero()
のほうが高速。
print(np.sum(a < 4))
# 4
print(np.sum(a % 2 == 0))
# 6
ndarrayの行・列ごとに条件を満たす要素数をカウント
多次元配列に対するnp.count_nonzero()
は、第二引数axis
を指定することで各軸(各次元)に対する処理となる。デフォルトはaxis=None
で、ndarray
全体に対する処理。
二次元配列の場合、axis=0
で列ごと、axis=1
で行ごとの処理となる。行・列ごとに条件を満たす要素数をカウントできる。
a = np.arange(12).reshape((3, 4))
print(a)
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
print(np.count_nonzero(a < 4))
# 4
print(np.count_nonzero(a < 4, axis=0))
# [1 1 1 1]
print(np.count_nonzero(a < 4, axis=1))
# [4 0 0]
引数keepdims
をTrue
とすると、結果も元のndarray
と同じ次元数となる。
print(np.count_nonzero(a < 4, keepdims=True))
# [[4]]
print(np.count_nonzero(a < 4, axis=0, keepdims=True))
# [[1 1 1 1]]
print(np.count_nonzero(a < 4, axis=1, keepdims=True))
# [[4]
# [0]
# [0]]
なお、np.count_nonzero()
の引数axis
はバージョン1.12
、引数keepdims
はバージョン1.19
で追加された。np.sum()
ではどちらもバージョン1.7
で追加されたので、古いバージョンではnp.sum()
を使えばよい。
np.any()で条件を満たす要素が一つでもあるか確認(全体、行・列ごと)
np.any()
は、第一引数のndarray
にTrue
の要素が一つでもあるときにTrue
を返し、そうでないときはFalse
を返す。
ndarray
に条件を満たす要素が一つでもあるかを確認できる。
a = np.arange(12).reshape((3, 4))
print(a)
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
print(np.any(a < 4))
# True
print(np.any(a > 100))
# False
np.any()
もnp.count_nonzero()
と同じように、第二引数axis
を指定すると行・列ごとの処理となる。
print(np.any(a < 4, axis=0))
# [ True True True True]
print(np.any(a < 4, axis=1))
# [ True False False]
例は省略するが、引数keepdims
も指定可能。
np.all()ですべての要素が条件を満たすか確認(全体、行・列ごと)
np.all()
は、第一引数のndarray
の要素がすべてTrue
のときにTrue
を返し、そうでないときはFalse
を返す。
ndarray
のすべての要素が条件を満たすかを確認できる。
a = np.arange(12).reshape((3, 4))
print(a)
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
print(np.all(a < 4))
# False
print(np.all(a < 100))
# True
np.all()
もnp.count_nonzero()
と同じように、第二引数axis
を指定すると行・列ごとの処理となる。
print(np.all(a < 4, axis=0))
# [False False False False]
print(np.all(a < 4, axis=1))
# [ True False False]
例は省略するが、引数keepdims
も指定可能。
複数条件を適用
複数の条件を組み合わせたい場合は、各条件式を括弧()
で囲んで&
(AND)や|
(OR)でつなぐ。否定~
(NOT)も使用可能。
a = np.arange(12).reshape((3, 4))
print(a)
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
print((a < 4) | (a % 2 == 0))
# [[ True True True True]
# [ True False True False]
# [ True False True False]]
print(np.count_nonzero((a < 4) | (a % 2 == 0)))
# 8
print(np.count_nonzero((a < 4) | (a % 2 == 0), axis=0))
# [3 1 3 1]
print(np.count_nonzero((a < 4) | (a % 2 == 0), axis=1))
# [4 2 2]
&
, |
ではなくand
, or
を使ったり、括弧を省略したりするとエラーになるので注意。
欠損値NaNをカウント
例えば、以下のようなデータが欠落したCSVファイルをndarray
として読み込むと欠損値NaN
が発生する。
a_nan = np.genfromtxt('data/src/sample_nan.csv', delimiter=',')
print(a_nan)
# [[11. 12. nan 14.]
# [21. nan nan 24.]
# [31. 32. 33. 34.]]
欠損値NaN
同士は==
で比較してもFalse
になってしまうため、欠損値をカウントするにはnp.isnan()
を使う。
print(np.nan == np.nan)
# False
print(a_nan == np.nan)
# [[False False False False]
# [False False False False]
# [False False False False]]
print(np.isnan(a_nan))
# [[False False True False]
# [False True True False]
# [False False False False]]
あとはこれまでの例と同じ。np.count_nonzero()
やnp.sum()
でTrue
の数をカウントすればよい。
print(np.count_nonzero(np.isnan(a_nan)))
# 3
print(np.count_nonzero(np.isnan(a_nan), axis=0))
# [0 1 2 0]
print(np.count_nonzero(np.isnan(a_nan), axis=1))
# [1 2 0]
欠損値ではない要素をカウントしたい場合は否定~
を使う。
print(~np.isnan(a_nan))
# [[ True True False True]
# [ True False False True]
# [ True True True True]]
欠損値の置換や削除については以下の記事を参照。
無限大infをカウント
要素が無限大inf
かどうかを判定する関数はnp.isinf()
。正負どちらの無限大もTrue
となる。
a_inf = np.array([-np.inf, 0, np.inf])
print(a_inf)
# [-inf 0. inf]
print(np.isinf(a_inf))
# [ True False True]
正の無限大に対してTrue
を返すnp.isposinf()
、負の無限大に対してTrue
を返すnp.isneginf()
もある。
print(np.isposinf(a_inf))
# [False False True]
print(np.isneginf(a_inf))
# [ True False False]
無限大は==
で比較できるので、正負どちらかのみを判定したい場合は==
を使ってもよい。
print(a_inf == np.inf)
# [False False True]
print(a_inf == -np.inf)
# [ True False False]
あとはこれまでの例と同じ。
print(np.count_nonzero(np.isinf(a_inf)))
# 2
print(np.count_nonzero(np.isposinf(a_inf)))
# 1
print(np.count_nonzero(np.isneginf(a_inf)))
# 1
無限大の演算などについては以下の記事を参照。