小能豆

numpy all/any 与测试单个元素的性能

py

我创建了一个不包含单个零的数组(我们忽略它包含零的概率,因为np.random.rand()均匀采样 [0,1))。我想检查所有值是否等于零(出于其他目的,数组可能包含所有零)。以下是一些时间安排。

令我惊讶的是,检查单个(非零)元素比使用np.all()或快约 2000 倍np.any()。我假设编译器在内部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)

阅读 15

收藏
2024-12-31

共1个答案

小能豆

当你写入 时a == 0,numpy 会创建一个新的布尔类型数组,将 中的每个元素a与 0 进行比较,并将结果存储在数组中。这种分配、初始化和随后的释放是成本高昂的原因。

a == 0请注意,您首先不需要显式。零整数始终计算为 False,非零整数计算为 True。np.all(a)相当于np.all(a != 0)。所以np.all(a==0)相当于not np.any(a)

2024-12-31