如何将Oracle数据库表中的数值原样导入Pandas DataFrame并导出为无小数的CSV文件
嘿,我之前也碰到过一模一样的问题!这其实是Oracle的NUMBER类型读取时的类型推断,加上Pandas导出CSV的默认格式导致的小坑——明明数据库里都是整数,导出CSV就平白多了个.0,特别闹心。
先搞明白问题出在哪
Oracle的NUMBER类型如果没显式指定小数位(比如只写了NUMBER而非NUMBER(10,0)),connectorx有时候会把它推断成float类型(尤其是列里可能存在NULL值的情况)。而float类型的数值哪怕是整数,Pandas用to_csv导出时默认也会加上.0;至于第一列为啥没带小数,大概率是数据分布刚好让connectorx把它推断成了int类型,纯属运气好。
给你几个实用的解决办法,按需选就行
办法一:读取数据时就指定列类型(从根源解决)
用connectorx的dtype参数,直接告诉它哪些列是整数类型,避免自动推断出错。
import connectorx as cx # 定义需要保持整数的列类型映射 dtype_map = { "col2": int, "col8": int, "col9": int } # 读取时传入dtype参数 df = cx.read_sql( conn="oracle+cx_oracle://你的用户名:密码@主机:端口/服务名", query="SELECT col1, col2, col3, col8, col9 FROM tabA", dtype=dtype_map )
⚠️ 注意:如果这些列里有NULL值,普通的int会报错,这时候换成Pandas支持空值的整数类型Int64(首字母大写)就行:
dtype_map = { "col2": "Int64", "col8": "Int64", "col9": "Int64" }
办法二:读取后手动转换列类型
如果已经把数据读到DataFrame里了,也可以事后把float类型的列转成整数类型:
# 情况1:列里没有NULL值,直接转int df["col8"] = df["col8"].astype(int) df["col9"] = df["col9"].astype(int) # 情况2:列里有NULL值,用支持空值的Int64 df["col8"] = df["col8"].astype("Int64") df["col9"] = df["col9"].astype("Int64")
办法三:导出CSV时指定格式(最快的临时解决方案)
如果不想改动DataFrame的结构,也可以在导出的时候直接指定float类型的输出格式,让整数显示成无小数的样子:
df.to_csv("你的输出文件.csv", float_format="%.0f", index=False)
这个方法特别适合临时导出用,不用改数据结构,一步到位。
额外提个小建议
可以先查一下Oracle表的列定义,用DESC tabA命令看看那些数值列是不是NUMBER(xx, 0)——如果是带0小数位的定义,大部分驱动都会直接识别成int;如果只是NUMBER,就容易被推断成float,这时候用上面的办法一就能彻底解决问题。
备注:内容来源于stack exchange,提问作者Kaustav Nandy

