【发布时间】:2013-08-26 02:03:25
【问题描述】:
我们用零初始化一个 numpy 数组,如下所示:
np.zeros((N,N+1))
但是我们如何检查给定 n*n numpy 数组矩阵中的所有元素是否为零。
如果所有值确实为零,则该方法只需要返回 True。
【问题讨论】:
我们用零初始化一个 numpy 数组,如下所示:
np.zeros((N,N+1))
但是我们如何检查给定 n*n numpy 数组矩阵中的所有元素是否为零。
如果所有值确实为零,则该方法只需要返回 True。
【问题讨论】:
如果你的数组中的所有元素都大于或等于0。我认为使用 sum 是最快的方法。
test = np.ones((128, 128, 128))
%%timeit
not np.any(test)
>>> 1.46 ms ± 9.09 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%%timeit
np.sum(test) == 0
>>> 646 µs ± 3.19 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
【讨论】:
这会起作用。
def check(arr):
if np.all(arr == 0):
return True
return False
【讨论】:
正如另一个答案所说,如果您知道 0 是数组中唯一可能的虚假元素,则可以利用真假评估。一个数组中的所有元素都是假的,如果其中没有任何真元素。*
>>> a = np.zeros(10)
>>> not np.any(a)
True
但是,答案声称any 比其他选项更快,部分原因是短路。截至 2018 年,Numpy 的 all 和 any 不会短路。
如果你经常做这种事情,很容易使用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)
* 有用的 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))
【讨论】:
此处发布的其他答案将起作用,但使用最清晰和最有效的功能是numpy.any():
>>> all_zeros = not np.any(a)
或
>>> all_zeros = not a.any()
numpy.all(a==0) 更受欢迎,因为它使用更少的RAM。 (它不需要由 a==0 术语创建的临时数组。)numpy.count_nonzero(a) 更快,因为它可以在找到第一个非零元素时立即返回。np.any() 不再使用“短路”逻辑,因此您不会看到小型阵列的速度优势。【讨论】:
any 和 all 会不短路。我相信它们是logical_or.reduce 和logical_and.reduce 的糖。比较一下我的短路is_in:all_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
如果您正在测试全零以避免在另一个 numpy 函数上出现警告,则将该行包装在 try, except 块中将省去在您感兴趣的操作之前进行零测试,即
try: # removes output noise for empty slice
mean = np.mean(array)
except:
mean = 0
【讨论】:
我会在这里使用 np.all,如果你有一个数组 a:
>>> np.all(a==0)
【讨论】:
np.all(a==a[0]) 来检查数组中的所有元素是否相同。非常感谢!
np.count_nonzero效率高一点。 %timeit num_of_non_zeros = np.count_nonzero(zeros_vector) 18.2 µs ± 386 ns 每个循环(平均值 ± 标准偏差。7 次运行,每次 100000 次循环)%timeit num_of_non_zeros = np.all((zeros_vector == 0)) 7.31 µs ±每个循环 41.6 ns(平均值 ± 标准偏差。7 次运行,每次 100000 次循环)
>>> np.count_nonzero(np.eye(4))
4
>>> np.count_nonzero([[0,1,7,0,0],[3,0,0,2,19]])
5
【讨论】:
not np.count_nonzero(np.eye(4)) 返回 True。
array.nonzero()[0].size == 0 在实践中往往更快