Python 测试 numpy 数组是否只包含零

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18395725/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 10:38:18  来源:igfitidea点击:

Test if numpy array contains only zeros

pythonnumpy

提问by IUnknown

We initialize a numpy array with zeros as bellow:

我们用零初始化一个 numpy 数组,如下所示:

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

But how do we check whether all elements in a given n*n numpy array matrix is zero.
The method just need to return a True if all the values are indeed zero.

但是我们如何检查给定的 n*n numpy 数组矩阵中的所有元素是否为零。
如果所有值确实为零,则该方法只需要返回 True 。

采纳答案by Prashant Kumar

Check out numpy.count_nonzero.

查看numpy.count_nonzero

>>> np.count_nonzero(np.eye(4))
4
>>> np.count_nonzero([[0,1,7,0,0],[3,0,0,2,19]])
5

回答by J. Martinot-Lagarde

I'd use np.all here, if you have an array a:

如果你有一个数组 a,我会在这里使用 np.all:

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

回答by Stuart Berg

The other answers posted here will work, but the clearest and most efficient function to use is numpy.any():

此处发布的其他答案将起作用,但最清晰、最有效的功能是numpy.any()

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

or

或者

>>> all_zeros = not a.any()
  • This is preferred over numpy.all(a==0)because it uses less RAM. (It does not require the temporary array created by the a==0term.)
  • Also, it is faster than numpy.count_nonzero(a)because it can return immediately when the first nonzero element has been found.
    • Edit:As @Rachel pointed out in the comments, np.any()no longer uses "short-circuit" logic, so you won't see a speed benefit for small arrays.
  • 这是首选,numpy.all(a==0)因为它使用较少的 RAM。(它不需要a==0术语创建的临时数组。)
  • 此外,它比numpy.count_nonzero(a)在找到第一个非零元素时立即返回要快。
    • 编辑:正如@Rachel 在评论中指出的那样,np.any()不再使用“短路”逻辑,因此您不会看到小数组的速度优势。

回答by ReaddyEddy

If you're testing for all zeros to avoid a warning on another numpy function then wrapping the line in a try, except block will save having to do the test for zeros before the operation you're interested in i.e.

如果您正在测试所有零以避免在另一个 numpy 函数上发出警告,然后将行包装在 try, except 块将省却在您感兴趣的操作之前对零进行测试,即

try: # removes output noise for empty slice 
    mean = np.mean(array)
except:
    mean = 0

回答by Rachel

As another answer says, you can take advantage of truthy/falsy evaluations if you know that 0is the only falsy element possibly in your array. All elements in an array are falsy iff there are not any truthy elements in it.*

正如另一个答案所说,如果您知道这0是数组中唯一可能的虚假元素,则可以利用真/假评估。如果数组中没有任何真元素,则数组中的所有元素都是假的。*

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

However, the answer claimed that anywas faster than other options due partly to short-circuiting. As of 2018, Numpy's alland anydo not short-circuit.

然而,答案声称这any比其他选项更快,部分原因是短路。截至 2018 年,Numpy'sallany没有短路.

If you do this kind of thing often, it's very easy to make your own short-circuiting versions using numba:

如果你经常做这种事情,很容易使用以下方法制作自己的短路版本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

These tend to be faster than Numpy's versions even when not short-circuiting. count_nonzerois the slowest.

即使没有短路,这些也往往比 Numpy 的版本快。count_nonzero是最慢的。

Some input to check performance:

检查性能的一些输入:

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]

Check:

查看:

## 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)

* Helpful alland anyequivalences:

* 有用的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))