可以将pandas Series转换为`int64`,但不能转换为`Int64`

cbwuti44  于 2023-04-28  发布在  其他
关注(0)|答案(1)|浏览(193)

我遇到了一个奇怪的类型转换问题。。我用整数值填充了一个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记录...)

s3fp2yjn

s3fp2yjn1#

正如Jason在他的评论中建议的那样,您的编辑解决了这个问题,因为舍入将8300000.000000001更改为8300000.0
这一点很重要,因为这意味着在类型转换之后,两个值仍然相等,因此它们满足numpy转换的“安全”转换规则。当转换为'Int64' pandas时,使用应用此规则的numpy.ndarray.astype函数。关于“安全”转换的详细信息可以在这里找到。
据我所知,没有办法要求pandas使用具有不同类型转换的numpy函数,因此首先舍入值是解决问题的方法。

相关问题