我创建了一个不包含单个零的数组(我们忽略它包含零的概率,因为np.random.rand()均匀采样 [0,1))。我想检查所有值是否等于零(出于其他目的,数组可能包含所有零)。以下是一些时间安排。
np.random.rand()
令我惊讶的是,检查单个(非零)元素比使用np.all()或快约 2000 倍np.any()。我假设编译器在内部np.all()用替换np.any()逆条件,并在第一次满足/违反条件时np.any()/np.all()返回(即编译器不会首先创建或值的整个数组)。True/False``True``False
np.all()
np.any()
np.any()/np.all()
True/False``True``False
np.all()当只需要检查一个元素时,为什么速度np.any()会慢很多?还是因为我输入了数组不包含全零的外部知识?对于全零数组,我猜对每个元素分别进行布尔比较可能会太慢。我不知道底层低级算法的性能,但每个元素都需要访问一次,无论是逐个访问还是创建一次整个布尔数组。
import numpy as np np.random.seed(100) a = np.random.rand(10418,144) %timeit a[0,0] == 0 %timeit (a == 0).all() %timeit np.all(a == 0) %timeit (a != 0).any() %timeit np.any(a != 0) # 400 ns ± 2.08 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) # 713 µs ± 382 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each) # 720 µs ± 1.17 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) # 711 µs ± 407 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each) # 723 µs ± 630 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each)
当你写入 时a == 0,numpy 会创建一个新的布尔类型数组,将 中的每个元素a与 0 进行比较,并将结果存储在数组中。这种分配、初始化和随后的释放是成本高昂的原因。
a == 0
a
a == 0请注意,您首先不需要显式。零整数始终计算为 False,非零整数计算为 True。np.all(a)相当于np.all(a != 0)。所以np.all(a==0)相当于not np.any(a)
np.all(a)
np.all(a != 0)
np.all(a==0)
not np.any(a)