在 Python 中计算 numpy ndarray 中非 NaN 元素的数量

我需要计算一个 ndarray 矩阵中非 NaN 元素的数量。如何在 Python 中有效地实现这一点?以下是我实现这一目标的简单代码:

import numpy as np


def numberOfNonNans(data):
count = 0
for i in data:
if not np.isnan(i):
count += 1
return count

是否有一个内置的功能,这在麻木? 效率是重要的,因为我正在做大数据分析。

谢谢你的帮助!

173640 次浏览
np.count_nonzero(~np.isnan(data))

~反转从 np.isnan返回的布尔矩阵。

np.count_nonzero计数的值不是0为假。 .sum应该给出相同的结果。但是使用 count_nonzero可能会更清楚

测试速度:

In [23]: data = np.random.random((10000,10000))


In [24]: data[[np.random.random_integers(0,10000, 100)],:][:, [np.random.random_integers(0,99, 100)]] = np.nan


In [25]: %timeit data.size - np.count_nonzero(np.isnan(data))
1 loops, best of 3: 309 ms per loop


In [26]: %timeit np.count_nonzero(~np.isnan(data))
1 loops, best of 3: 345 ms per loop


In [27]: %timeit data.size - np.isnan(data).sum()
1 loops, best of 3: 339 ms per loop

data.size - np.count_nonzero(np.isnan(data))似乎是这里最快的。其他数据可能会给出不同的相对速度结果。

另一种方法是过度索引,但速度稍慢一些。

np.isnan(data)[np.isnan(data) == False].size


In [30]: %timeit np.isnan(data)[np.isnan(data) == False].size
1 loops, best of 3: 498 ms per loop

np.isnan(data)==操作符的双重使用可能有点过分,所以我只是为了完整性才发布了答案。

快速编写的备选方案

即使不是最快的选择,如果性能不是问题,你也可以使用:

sum(~np.isnan(data)).

演出:

In [7]: %timeit data.size - np.count_nonzero(np.isnan(data))
10 loops, best of 3: 67.5 ms per loop


In [8]: %timeit sum(~np.isnan(data))
10 loops, best of 3: 154 ms per loop


In [9]: %timeit np.sum(~np.isnan(data))
10 loops, best of 3: 140 ms per loop

为了确定数组是否是稀疏的,它可能有助于获得一定比例的 nan 值

np.isnan(ndarr).sum() / ndarr.size

If that proportion exceeds a threshold, then use a sparse array, e.g. Https://sparse.pydata.org/en/latest/

len([i for i in data if np.isnan(i) == True])