2009-05-26 94 views
48

我需要编写一个函数来检测输入是否包含至少一个非数字值。如果找到一个非数字值,我将引发一个错误(因为计算只能返回一个数值)。输入数组的维数是事先不知道的 - 无论ndim如何,函数都应该给出正确的值。作为一种额外的复杂功能,输入可以是单个浮点数或numpy.float64,或者甚至是像零维数组那样的奇怪球体。检测NumPy数组是否至少包含一个非数字值?

解决此问题的显而易见的方法是编写一个递归函数,该函数遍历数组中的每个可迭代对象,直到找到一个非迭代。它将在每个不可迭代对象上应用numpy.isnan()函数。如果至少找到一个非数字值,则该函数将立即返回False。否则,如果迭代中的所有值都是数值,它最终将返回True。

这工作得很好,但它很慢,我期望NumPy有一个更好的方法来做到这一点。什么是更快,更numpyish的选择?

这里是我的样机:

def contains_nan(myarray): 
    """ 
    @param myarray : An n-dimensional array or a single float 
    @type myarray : numpy.ndarray, numpy.array, float 
    @returns: bool 
    Returns true if myarray is numeric or only contains numeric values. 
    Returns false if at least one non-numeric value exists 
    Not-A-Number is given by the numpy.isnan() function. 
    """ 
    return True 
+3

您的`contains_nan`描述看起来很可疑:“如果至少一个非数字值存在返回false”。如果数组包含NaN,我会希望`contains_nan`返回`True`。 – 2009-05-26 18:00:59

+0

输入如array(['None','None'],dtype = object)`?这样的输入是否会引发异常? – 2015-06-08 14:47:52

+0

不要在x中使用float('nan')。这是行不通的。 – 2016-10-13 22:08:00

回答

78

这应该比迭代更快,无论形状会工作。

numpy.isnan(myarray).any() 

编辑:30X速度快:

import timeit 
s = 'import numpy;a = numpy.arange(10000.).reshape((100,100));a[10,10]=numpy.nan' 
ms = [ 
    'numpy.isnan(a).any()', 
    'any(numpy.isnan(x) for x in a.flatten())'] 
for m in ms: 
    print " %.2f s" % timeit.Timer(m, s).timeit(1000), m 

结果:

0.11 s numpy.isnan(a).any() 
    3.75 s any(numpy.isnan(x) for x in a.flatten()) 

奖励:它工作正常,非数组NumPy的类型:

>>> a = numpy.float64(42.) 
>>> numpy.isnan(a).any() 
False 
>>> a = numpy.float64(numpy.nan) 
>>> numpy.isnan(a).any() 
True 
+0

with numpy 1.7 flatten()版本只有第一个版本的两倍 – 2013-10-09 14:39:27

3

随着numpy的1.3或svn你可以这样做

In [1]: a = arange(10000.).reshape(100,100) 

In [3]: isnan(a.max()) 
Out[3]: False 

In [4]: a[50,50] = nan 

In [5]: isnan(a.max()) 
Out[5]: True 

In [6]: timeit isnan(a.max()) 
10000 loops, best of 3: 66.3 µs per loop 

在早期版本中,对比nans的治疗并不一致。

9

如果无穷大是一个可能的值,我会用numpy.isfinite

numpy.isfinite(myarray).all() 

如果上述计算结果为True,然后myarray不包含,numpy.nannumpy.inf-numpy.inf值。

numpy.nan将与numpy.inf值确定,例如:

In [11]: import numpy as np 

In [12]: b = np.array([[4, np.inf],[np.nan, -np.inf]]) 

In [13]: np.isnan(b) 
Out[13]: 
array([[False, False], 
     [ True, False]], dtype=bool) 

In [14]: np.isfinite(b) 
Out[14]: 
array([[ True, False], 
     [False, False]], dtype=bool) 
2

(np.where(np.isnan(A)))[0].shape[0]将比0更大如果A包含nan的至少一种元素,A可以是n x m矩阵。

例子:

import numpy as np 

A = np.array([1,2,4,np.nan]) 

if (np.where(np.isnan(A)))[0].shape[0]: 
    print "A contains nan" 
else: 
    print "A does not contain nan" 
相关问题