numpy:区分/转换不同类型的nan?

时间:2015-10-27 13:48:12

标签: arrays numpy

我一直看到很多错误,如:

FloatingPointError: invalid value encountered in multiply

我从磁盘加载的一些数据(使用astropy.io.fits)。它似乎与this issue有关,即我有一个'信号纳'而不是'安静的南'。

这是有问题的,因为我不能简单地“清理”数据。如果我尝试将数组转换为具有相同dtype的数组,例如:

arr = arr.astype(arr.dtype)

nan保持不变,即np.isnan生成警告,但如果我更改了dtype

# arr.dtype is float32 originally
arr = arr.astype(np.float64)

警告消失了乘法/ np.isnan / etc。我不想使用此解决方法,因为它需要更改数组的大小。

那么,我怎样才能区分那些没有回复到nan的字符串表示的?是否有(便宜的)方式将所有'信号'转换为安静的?

2 个答案:

答案 0 :(得分:1)

这将使用默认的quiet nan:

替换arr中的所有nans
with np.errstate(invalid='ignore'):
    arr[np.isnan(arr)] = np.nan

对于它的价值,这里有一个快速的issnan函数,仅对信号nans为True:

import numpy as np

def issnan(a):
    """
    Returns True where elements of `a` are signaling nans.

    `a` must be a numpy array with data type float32 or float64.

    This function assumes IEEE 754 floating point representation, and
    that the first (left-most) bit in the mantissa is the "quiet" bit.
    That is, a nan value with this bit set to 0 is a signaling nan.
    """
    if a.dtype == np.float64:
        v = a.view(np.uint64)
        # t1 is true where all the exponent bits are 1 and the
        # quiet bit is 0.
        t1 = (v & 0x7FF8000000000000) == 0x7FF0000000000000
        # t2 is non-zero where at least one bit (not including
        # the quiet bit) in the mantissa is 1.  (If the mantissa
        # is all zeros and the exponent is all ones, the value is
        # infinity.)
        t2 = v & 0x0007FFFFFFFFFFFF
        return np.logical_and(t1, t2)
    elif a.dtype == np.float32:
        v = a.view(np.uint32)
        t1 = (v & 0x7FC00000) == 0x7F800000
        t2 = v & 0x003FFFFF
        return np.logical_and(t1, t2)
    else:
        raise ValueError('a must have dtype float32 or float64')

例如,

In [151]: z
Out[151]: array([ nan,  nan,  inf,   1.], dtype=float32)

In [152]: [hex(r) for r in z.view(np.uint32)]
Out[152]: ['0x7f800001L', '0x7fc00000L', '0x7f800000L', '0x3f800000L']

In [153]: issnan(z)
Out[153]: array([ True, False, False, False], dtype=bool)

答案 1 :(得分:0)

有点操作的答案取决于你愿意依赖系统的方式。引自wikipedia

  

...大多数处理器...如果NaN是安静的,则将发信号/静默位设置为非零,如果NaN发信号则将其设置为零。因此,在这些处理器上,该位代表'is_quiet'标志。

信号/静默位通常第一个尾数位。因此,您可以根据需要设置一个函数来旋转该位。