pandas merge()操作将int转为float,已修复版本1.3.0仍复现原因问询
pandas left join后int列转float问题原因及解决方案
- 你遇到的类型转换不是未修复的bug,是pandas旧版本数值类型系统的固有特性:pandas 1.3.0 版本中,默认使用的numpy原生
int64类型不支持存储空值NaN,当left join产生未匹配行时,对应列会出现NaN,因此整列会被向上转型为兼容NaN的float64类型。 - 网传该问题“已修复”的说法,大多是指无空值生成的场景(比如inner join、双方主键完全匹配的left join),这类场景下merge不会修改原int列类型。
你提供的复现代码如下:
import pandas as pd df1 = pd.DataFrame([{'n': '001', 'b': 0}, {'n': '002', 'b': 1}]) df2 = pd.DataFrame([{'n': '001', 'c': 3}]) df3 = pd.merge(df1, df2, how='left', on='n') print(df3) # n b c # 0 001 0 3.0 # 1 002 1 NaN print(df2.dtypes) # n object # c int64 # dtype: object print(df3.dtypes) # n object # b int64 # c float64 # dtype: object print(pd.__version__) # 1.3.0
解决方案
方案1:使用pandas可空整数类型(推荐,1.0+版本支持)
提前将原表的int列指定为pandas专属的可空整数类型Int64(首字母大写,区别于numpy的int64),该类型支持同时存储整数和NaN,merge后不会发生类型转换:
# 定义df2时指定c列为可空整数类型 df2 = pd.DataFrame([{'n': '001', 'c': 3}]).astype({'c': 'Int64'}) df3 = pd.merge(df1, df2, how='left', on='n') print(df3.dtypes['c']) # Int64
方案2:merge完成后手动转换类型
如果不想修改原表类型,可以在merge后对结果列做类型转换,空值可以根据业务需求填充后再转int:
# 空值填充为指定值(比如0)后转int df3['c'] = df3['c'].fillna(0).astype('int64') # 若需要保留空值,也可以直接转成Int64 df3['c'] = df3['c'].astype('Int64')
内容的提问来源于stack exchange,提问作者Cuteufo
相关产品推荐
相关产品推荐

