我一直看到很多错误,如:
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的字符串表示的?是否有(便宜的)方式将所有'信号'转换为安静的?
答案 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'标志。
信号/静默位通常第一个尾数位。因此,您可以根据需要设置一个函数来旋转该位。