Numpy确实对待浮动(' nan')并以不同方式浮动 - 转换为无

时间:2016-02-10 18:22:50

标签: python arrays numpy

我想从普通数组创建一个Numpy数组并将nan值转换为None - 但成功取决于天气,第一个值是"正常"浮动,或float('nan')

这是我的代码,从初始数组开始:

print(a)
array('d', [3.2345, nan, 2.0, 3.2, 1.0, 3.0])
print(b)
array('d', [nan, nan, 2.0, 3.2, 1.0, 3.0])

现在我想通过矢量化函数将所有nan值交换到Python None

def convert(x):
    if x != x:
        return None
    else:
        return x

convert_vec = numpy.vectorize(convert)

简单,但会产生两种不同的结果:

numpy.asarray(convert_vec(a))

array([[ 3.2345,  2.    ,  1.    ], [    nan,  3.2   ,  3.    ]])

numpy.asarray(convert_vec(b))
array([[None, 2.0, 1.0], [None, 3.2, 3.0]], dtype=object)

这是为什么?是的,我可以看到一个小差异 - 第二个有objectdtype。但是使用numpy.asarray(convert_vec(a), dtype=object)修正了它 - object都为dtype - 但它并没有改变结果的差异。

2 个答案:

答案 0 :(得分:2)

np.nan是浮点值,None不是数字。

In [464]: np.array([1,2,np.nan,3])
Out[464]: array([  1.,   2.,  nan,   3.])

In [465]: np.array([1,2,None,3])
Out[465]: array([1, 2, None, 3], dtype=object)

In [466]: np.array([1,2,None,3],dtype=float)
Out[466]: array([  1.,   2.,  nan,   3.])

如果您尝试创建包含None的数组,则结果将为dtype=object数组。如果您坚持使用float dtype,None将转换为nan

vectorize的情况下,如果您没有指定返回dtype,则会从第一个元素中推断出它。

您的示例有点令人困惑(您需要编辑它们),但我认为

convert(np.nan) => None
convert(123) => 123

所以

convert_vec([123,nan,...]) => [123, nan, ...],dtype=float
convert_vec([nan,123,...]) => [None, 123,...],dtype=object
  • 尝试将np.nan转换为None是一个坏主意,除了可能用于显示目的。

  • vectorize没有明确的结果dtype规范是一个坏主意

  • 这可能不是vectorize的好用。

以下是转换nan值的替代方法:

In [467]: a=np.array([1,2,np.nan,34,np.nan],float)    
In [468]: a
Out[468]: array([  1.,   2.,  nan,  34.,  nan])
In [471]: ind=a!=a   
In [472]: ind
Out[472]: array([False, False,  True, False,  True], dtype=bool)

In [473]: a[ind]=0   # not trying None
In [474]: a
Out[474]: array([  1.,   2.,   0.,  34.,   0.])

或使用蒙面数组:

In [477]: am=np.ma.masked_invalid(a)

In [478]: am
Out[478]: 
masked_array(data = [1.0 2.0 -- 34.0 --],
             mask = [False False  True False  True],
       fill_value = 1e+20)

In [479]: am.filled(0)
Out[479]: array([  1.,   2.,   0.,  34.,   0.])

答案 1 :(得分:-1)

hpaulj解释得很好,这里有一个简单的演示如何做到:

a = [3.2345, numpy.nan, 2.0, 3.2, 1.0, 3.0]
print [i if i is not numpy.nan else None for i in a]