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


87

我需要计算一个numpy 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 

numpy中有内置函数吗?效率很重要,因为我正在进行大数据分析。

Thnx寻求任何帮助!


2
这个问题似乎
不合时宜,

1
您是说有效的内存?
Ashwini Chaudhary 2014年

+1我当时在考虑CPU时间,但是,为什么不同时使用内存呢?越快越便宜越好=)
jjepsuomi 2014年

3
@jjepsuomi可以使用内存有效的版本sum(not np.isnan(x) for x in a),但与@ M4rtini numpy版本相比,它的速度较慢。
Ashwini Chaudhary 2014年

@AshwiniChaudhary非常感谢!我需要查看在我的应用程序中哪个更重要=)
jjepsuomi

Answers:


161
np.count_nonzero(~np.isnan(data))

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

np.count_nonzero计算不为0 \ false的值。.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))似乎几乎不是最快的。其他数据可能会给出不同的相对速度结果。


+1 @ M4rtini再次感谢您!你很棒!; DI将尽快接受您的回答:)
jjepsuomi

3
也许甚至numpy.isnan(array).sum()?我不是很精通numpy。
msvalkon 2014年

2
@msvalkon,它将计算NaN的数量,而OP想要非NaN元素的数量。
falsetru


5
@msvalkon答案的扩展:data.size - np.isnan(data).sum()效率会更高。
丹尼尔(Daniel)

10

快速写作替代

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

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

此答案提供的总和与计算元素的数量不同...您应该使用它len
BenT

@BenT满足特定条件的布尔数组元素的总和是相同的,只要子集数组的len具有满足特定条件的元素即可。您能说明这是哪里错吗?
GM

1
我忘了布尔值的错误得到了回报。
BenT


2

一种替代方法,但是有点慢,替代方法是在索引上进行。

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)==运算符的重复使用可能会有点过大,因此我仅出于完整性而发布答案。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.