pandas DataFrame转列表时如何避免int64变float、保持数据类型完整性
问题原因
pandas 原生的 int64 数据类型不支持缺失值 NaN,如果你的 DataFrame 中原本为 int 类型的列存在显性/隐性的缺失值,pandas 会自动将整列的类型向上转型为 float64 来兼容 NaN,就算你肉眼观测不到缺失值,也可能是数据导入、合并、切片等操作过程中触发了自动类型转换。
另外你调用的 df.values 会返回 numpy 数组,numpy 在处理存在类型歧义的列时也会触发类型提升,转列表后会保留 float 格式,最终导致插入 Oracle 时类型不匹配。
解决方法
- 先确认列的实际类型,执行
print(df['目标列名'].dtype)检查转换前的列类型是否已经被转为 float:- 允许填充缺失值的场景:直接填充缺失值后手动转回 int 类型,示例代码:
df['目标列名'] = df['目标列名'].fillna(0).astype('int64') - 需要保留缺失值的场景:使用 pandas 支持空值的 nullable 整数类型
Int64(首字母大写),既能保留 NaN 也能保证整数语义:df['目标列名'] = df['目标列名'].astype('Int64')
- 允许填充缺失值的场景:直接填充缺失值后手动转回 int 类型,示例代码:
- 更换转列表的实现方式,避免
values带来的类型强制转换:# 用itertuples逐行读取,保留原始类型 df_list = [list(row) for row in df.itertuples(index=False)] - 针对插入 Oracle 的场景,更推荐直接用
to_sql方法写入,不用手动转列表,通过指定 dtype 映射直接对齐数据库字段类型,完全避免类型错乱问题,示例代码:from sqlalchemy import types # 按Oracle表的实际字段类型定义映射关系 dtype_mapping = { 'int类型列名': types.NUMERIC(precision=10, scale=0), '字符串列名': types.VARCHAR(length=255), # 其他列按需补充 } df.to_sql( name='目标Oracle表名', con=你的数据库连接实例, if_exists='append', index=False, dtype=dtype_mapping )
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

