numpy配列にゼロのみが含まれているかどうかをテストします


92

numpy配列を次のようにゼロで初期化します。

np.zeros((N,N+1))

しかし、与えられたn * n numpy配列行列のすべての要素がゼロであるかどうかをどのようにチェックするのですか?
すべての値が実際にゼロの場合、メソッドはTrueを返すだけです。

回答:



161

ここに投稿された他の回答は機能しますが、使用する最も明確で最も効率的な関数はnumpy.any()次のとおりです。

>>> all_zeros = not np.any(a)

または

>>> all_zeros = not a.any()
  • numpy.all(a==0)RAMの使用量が少ないため、この方法をお勧めします。(a==0用語によって作成された一時的な配列は必要ありません。)
  • また、numpy.count_nonzero(a)最初のゼロ以外の要素が見つかったときにすぐに戻ることができるため、より高速です。
    • 編集: @Rachelがコメントで指摘したように、np.any()「短絡」ロジックを使用しなくなったため、小さな配列の速度の利点はわかりません。

2
分前の時点で、numpyののanyallやるではないショート。私はそれらがのための砂糖であるlogical_or.reduceと信じていますlogical_and.reduce。お互いと私の短絡を比較してくださいis_inall_false = np.zeros(10**8) all_true = np.ones(10**8) %timeit np.any(all_false) 91.5 ms ± 1.82 ms per loop %timeit np.any(all_true) 93.7 ms ± 6.16 ms per loop %timeit is_in(1, all_true) 293 ns ± 1.65 ns per loop
Rachel

2
それは素晴らしい点です、ありがとう。これは、短絡のように見える使用振る舞いをするが、それはいくつかの時点で失われました。この質問への回答には興味深い議論があります。
スチュアートバーグ

50

配列がある場合は、ここでnp.allを使用しますa:

>>> np.all(a==0)

3
私はこの答えがゼロ以外の値もチェックするのが好きです。たとえば、を実行すると、配列内のすべての要素が同じであるかどうかを確認できnp.all(a==a[0])ます。どうもありがとう!
aignas 14年

9

別の答えが言うように、それが0配列内の唯一の偽の要素であることがわかっている場合は、真実/偽の評価を利用できます。配列内のすべての要素は、その中に真実の要素がない場合に偽です。

>>> a = np.zeros(10)
>>> not np.any(a)
True

しかし、答えは、any一部短絡のために他のオプションよりも速いと主張しました。2018年現在、Numpy allany 短絡しないでください

この種のことを頻繁に行う場合、以下を使用して独自の短絡バージョンを作成するのは非常に簡単ですnumba

import numba as nb

# short-circuiting replacement for np.any()
@nb.jit(nopython=True)
def sc_any(array):
    for x in array.flat:
        if x:
            return True
    return False

# short-circuiting replacement for np.all()
@nb.jit(nopython=True)
def sc_all(array):
    for x in array.flat:
        if not x:
            return False
    return True

これらは、短絡していない場合でも、Numpyのバージョンよりも高速になる傾向があります。 count_nonzero最も遅いです。

パフォーマンスを確認するための入力:

import numpy as np

n = 10**8
middle = n//2
all_0 = np.zeros(n, dtype=int)
all_1 = np.ones(n, dtype=int)
mid_0 = np.ones(n, dtype=int)
mid_1 = np.zeros(n, dtype=int)
np.put(mid_0, middle, 0)
np.put(mid_1, middle, 1)
# mid_0 = [1 1 1 ... 1 0 1 ... 1 1 1]
# mid_1 = [0 0 0 ... 0 1 0 ... 0 0 0]

小切手:

## count_nonzero
%timeit np.count_nonzero(all_0) 
# 220 ms ± 8.73 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit np.count_nonzero(all_1)
# 150 ms ± 4.56 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

### all
# np.all
%timeit np.all(all_1)
%timeit np.all(mid_0)
%timeit np.all(all_0)
# 56.8 ms ± 3.41 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
# 57.4 ms ± 1.76 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
# 55.9 ms ± 2.13 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

# sc_all
%timeit sc_all(all_1)
%timeit sc_all(mid_0)
%timeit sc_all(all_0)
# 44.4 ms ± 2.49 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
# 22.7 ms ± 599 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
# 288 ns ± 6.36 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

### any
# np.any
%timeit np.any(all_0)
%timeit np.any(mid_1)
%timeit np.any(all_1)
# 60.7 ms ± 1.38 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
# 60 ms ± 287 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
# 57.7 ms ± 1.12 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

# sc_any
%timeit sc_any(all_0)
%timeit sc_any(mid_1)
%timeit sc_any(all_1)
# 41.7 ms ± 1.24 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
# 22.4 ms ± 1.51 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
# 287 ns ± 12.7 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

*参考allany同値:

np.all(a) == np.logical_not(np.any(np.logical_not(a)))
np.any(a) == np.logical_not(np.all(np.logical_not(a)))
not np.all(a) == np.any(np.logical_not(a))
not np.any(a) == np.all(np.logical_not(a))

-9

別のnumpy関数の警告を回避するためにすべてのゼロをテストしている場合は、行を試行でラップします。ただし、ブロックでは、関心のある操作の前にゼロのテストを実行する必要がなくなります。

try: # removes output noise for empty slice 
    mean = np.mean(array)
except:
    mean = 0
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.