我正在寻找最快的方法来检查NaN (np.nan
)在NumPy数组X
中的出现情况。np.isnan(X)
是不可能的,因为它构建了一个形状为X.shape
的布尔数组,这可能是巨大的。
我试过np.nan in X
,但似乎不起作用,因为np.nan != np.nan
。有没有一种既快速又节省内存的方法来做到这一点?
(对于那些会问“有多大”的人:我不知道。这是库代码的输入验证。)
发布于 2011-07-19 01:17:19
我觉得np.isnan(np.min(X))
应该按你说的做。
发布于 2011-07-19 05:19:21
即使有一个公认的答案,我也想演示一下(在Vista上使用Python 2.7.2和Numpy 1.6.0 ):
In []: x= rand(1e5)
In []: %timeit isnan(x.min())
10000 loops, best of 3: 200 us per loop
In []: %timeit isnan(x.sum())
10000 loops, best of 3: 169 us per loop
In []: %timeit isnan(dot(x, x))
10000 loops, best of 3: 134 us per loop
In []: x[5e4]= NaN
In []: %timeit isnan(x.min())
100 loops, best of 3: 4.47 ms per loop
In []: %timeit isnan(x.sum())
100 loops, best of 3: 6.44 ms per loop
In []: %timeit isnan(dot(x, x))
10000 loops, best of 3: 138 us per loop
因此,真正有效的方法可能在很大程度上取决于操作系统。无论如何,基于dot(.)
的似乎是最稳定的。
发布于 2016-12-02 19:17:13
如果你熟悉numba,它允许创建一个快速短路(一旦找到NaN就停止)功能:
import numba as nb
import math
@nb.njit
def anynan(array):
array = array.ravel()
for i in range(array.size):
if math.isnan(array[i]):
return True
return False
如果没有NaN
,函数实际上可能比np.min
慢,我认为这是因为np.min
对大型数组使用了多进程:
import numpy as np
array = np.random.random(2000000)
%timeit anynan(array) # 100 loops, best of 3: 2.21 ms per loop
%timeit np.isnan(array.sum()) # 100 loops, best of 3: 4.45 ms per loop
%timeit np.isnan(array.min()) # 1000 loops, best of 3: 1.64 ms per loop
但是如果数组中有一个NaN,特别是如果它的位置是低索引,那么它的速度要快得多:
array = np.random.random(2000000)
array[100] = np.nan
%timeit anynan(array) # 1000000 loops, best of 3: 1.93 µs per loop
%timeit np.isnan(array.sum()) # 100 loops, best of 3: 4.57 ms per loop
%timeit np.isnan(array.min()) # 1000 loops, best of 3: 1.65 ms per loop
使用Cython或C扩展可以实现类似的结果,这些扩展稍微复杂一些(或者像bottleneck.anynan
一样容易获得),但最终与我的anynan
函数的功能相同。
https://stackoverflow.com/questions/6736590
复制相似问题