我遇到了一个奇怪的类型转换问题。。我用整数值填充了一个pandas类型的'float'列。当然,它们被表示为浮点算术数字,但仍然“精确”到int精度。将它们转换为int
工作起来很有魅力,但直接转换为Int
会崩溃。
假设pandas DataFrame pp
有一个列Value
。所有写入其中的值都是'int',然后保存为类型float
。
print(f"pp['Value']:\n{pp['Value']}")
pp['Value']:
0 3500000.0
1 600000.0
2 400000.0
3 8300000.0
4 5700000.0
5 4400000.0
Name: Value, dtype: float64
显然pp['Value']
的dtype是float
,因为它可能包含NaN
(即使在这里,所有值都是整数)。
现在我希望这个系列的类型是Int64
。应该工作,对吧?但是:不执行:pp['Value'].astype('Int64')
引发TypeError: cannot safely cast non-equivalent float64 to int64
嗯?一个int
变成了不可转换为float
?好吧,这是可能发生的..所以让我们看看我们是否可以安全地转换为int
?[注意:仅适用于此处的示例。如果系列包含NaN
,则不是解决方案]
Appraoch A:将序列转换为int64
-工作起来很有魅力(数字真的都是整数可转换的):
pp['Value'] = pp['Value'].astype('int64')
print(f"pp['Value']:\n{pp['Value']}")
pp['Value']:
0 3500000
1 600000
2 400000
3 8300000
4 5700000
5 4400000
Name: Value, dtype: int64
好吧,那么...什么??转换到int
工作,而Int
失败?等一下..
方法B:让我们仔细看看,单独转换每个元素,并检查是否有任何值有一些奇怪的浮点算术问题。事实上,我们看到1个案例失败了:第四个值显示为.0000001的奇怪浮点算术。但是:无论如何,pandas知道如何将其转换为int
。所有值都可以很好地转换,正如我所希望的那样:
for idx, row in pp.iterrows():
print(f"{idx}: value = {row['Value']}, residual vs. int: {row['Value']%row['Value']}, int value: {int(row['Value'])}")
0: value = 3500000.0, residual vs. int: 0.0, int value: 3500000
1: value = 600000.0, residual vs. int: 0.0, int value: 600000
2: value = 400000.0, residual vs. int: 0.0, int value: 400000
3: value = 8300000.000000001, residual vs. int: 0.0, int value: 8300000
4: value = 5700000.0, residual vs. int: 0.0, int value: 5700000
5: value = 4400000.0, residual vs. int: 0.0, int value: 4400000
所以:等一下......这里发生了什么?我可以将int
输入到浮点列中,遭受浮点算术问题。好的,明白了。但是,虽然我可以安全地转换回int
(所有值单独或整个系列),但我不能转换为Int64
??
--〉为什么pandas/python本身就知道如何转换为int64
,而转换为Int64
会显示浮点运算问题?
编辑注解:
pp['Value'] = pp['Value'].round().astype('Int64')
确实是一个解决方法..这应该是完全不必要的,因为pp ['Value'].astype('int')可以工作(当然,除了NaN
记录...)
1条答案
按热度按时间s3fp2yjn1#
正如Jason在他的评论中建议的那样,您的编辑解决了这个问题,因为舍入将
8300000.000000001
更改为8300000.0
。这一点很重要,因为这意味着在类型转换之后,两个值仍然相等,因此它们满足numpy转换的“安全”转换规则。当转换为'Int64' pandas时,使用应用此规则的
numpy.ndarray.astype
函数。关于“安全”转换的详细信息可以在这里找到。据我所知,没有办法要求pandas使用具有不同类型转换的numpy函数,因此首先舍入值是解决问题的方法。