【发布时间】:2021-06-06 11:35:11
【问题描述】:
我遇到了一些我觉得奇怪的行为并复制了它。很简单,为什么
np.int64(np.float64(np.nan))
输出
-9223372036854775808
(正如 cmets 中指出的,是的,这是 -2^63,双面 int64 的最大负值)
如果相关或感兴趣,我最初的用例是查看 np.float64 类型的数据帧索引并转换为 np.int64(我通常不会无缘无故地嵌套类型,如上面的简化示例) . 从示例数据框开始:
0 1
NaN 1 2
1.0 3 4
NaN 5 6
然后运行:
print(df.index.values[0])
print(type(df.index.values[0]))
print(df.index.values[0].astype(np.int64))
print(type(df.index.values[0].astype(np.int64)))
打印:
nan
<class 'numpy.float64'>
-9223372036854775808
<class 'numpy.int64'>
但是,使用 python 类型你不能将 float nan 转换为 int:
print(np.nan)
print(type(np.nan))
print(np.nan.astype(np.int64))
出来:
nan
<class 'float'>
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-130-0d779433eac7> in <module>
1 print(np.nan)
2 print(type(np.nan))
----> 3 print(np.nan.astype(np.int64))
AttributeError: 'float' object has no attribute 'astype'
虽然在实践中我能够将 nans 更改为我知道不会是键 (0) 的值 - 我很好奇为什么类 np.float64 类型会这样表现?
【问题讨论】:
-
整数值没有 NaN 值,因此转换 NaN 可能是未定义的,特别是如果底层库是用 C 实现的。
-
在Python中进行转换实际上是
import math; int(math.nan),这会导致ValueError:Python拦截无效转换。 -
是 numpy 的 C 利用率导致它的预感还是你确定? (只是好奇,因为这听起来像是一个合理的原因)。在其他地方搜索谷歌时,我无法轻松找到对这个问题的参考。 (我认为即使搜索大的负整数也可以,但没有)。
-
相关 NumPy 问题:github.com/numpy/numpy/issues/4592。这可能是 NumPy 中的一个错误:
numpy.float64(numpy.nan)抛出一个 ValueError,numpy.int64(numpy.float64(numpy.nan))产生 i64 的最小值(对于 i32、u32、u64 类似)。 -
这本身不是 C 问题(有关此类转换的 C(非)行为,请参阅 stackoverflow.com/questions/10366485/…),但它看起来肯定是 NumPy 问题。