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
Test if numpy array contains only zeros
提问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.
>>> 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 thea==0
term.) Also, it is faster thannumpy.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.
- Edit:As @Rachel pointed out in the comments,
- 这是首选,
numpy.all(a==0)
因为它使用较少的 RAM。(它不需要a==0
术语创建的临时数组。) 此外,它比numpy.count_nonzero(a)
在找到第一个非零元素时立即返回要快。- 编辑:正如@Rachel 在评论中指出的那样,
np.any()
不再使用“短路”逻辑,因此您不会看到小数组的速度优势。
- 编辑:正如@Rachel 在评论中指出的那样,
回答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 0
is 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 any
was faster than other options due partly to short-circuiting. As of 2018, Numpy's all
and any
do not short-circuit.
然而,答案声称这any
比其他选项更快,部分原因是短路。截至 2018 年,Numpy'sall
并any
没有短路.
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_nonzero
is 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 all
and any
equivalences:
* 有用的all
和any
等效的:
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))