pandas.to_csv将长数字转为科学计数法是因为默认数值类型推断及numpy浮点打印机制,且Excel打开时会二次解析导致精度丢失;根本解决需在读取时用dtype=str或converters强制字符串类型,写出前确保列为object类型并转str,配合quoting=csv.QUOTE_NONNUMERIC;对非浮点字段禁用float_format,终极方案是绕过pandas直接用csv.writer手动控制。

为什么 pandas.to_csv 会把长数字转成科学计数法?
因为 pandas 默认启用 float_format=None,且底层用 numpy 打印浮点数时自动触发科学计数法——哪怕你传的是整型字符串或高精度数字。更麻烦的是,Excel 打开 CSV 时还会二次“优化”:把看起来像数字的字段(比如 1234567890123456789)直接当 float64 解析,立刻丢掉末尾几位。
用 dtype + converters 强制保留原始字符串格式
关键不是“禁止科学计数法”,而是不让 pandas 把字段当数值处理。最稳的方式是在读入和写出两个环节都做类型干预:
- 读取时用
dtype=str或converters={col: str},避免 pandas 自动推断为int64/float64 - 写出前确认目标列是
object类型且内容为字符串,例如df['id'] = df['id'].astype(str) - 写入时不加
float_format(它只对数值型生效,对字符串无效),但要加quoting=csv.QUOTE_NONNUMERIC防止含逗号的字符串被截断
示例:
import pandas as pd
import csv
df = pd.DataFrame({'id': ['12345678901234567890', '98765432109876543210']})
df.to_csv('out.csv', index=False, quoting=csv.QUOTE_NONNUMERIC)
如果必须保留数值类型,用 float_format 控制小数位但不解决整数精度
float_format 只影响浮点数输出格式,对整数列无效;而且它不能防止 Excel 后续解析错误。但它在某些导出场景下有用:
立即学习“Python免费学习笔记(深入)”;
- 仅适用于真实浮点字段(如金额、测量值)
- 设为
float_format='%.0f'可强制显示为整数形式,但前提是该列确实是float64且原始值在2**53范围内,否则精度早已丢失 - 设为
float_format='%.15g'比默认更稳定,但依然无法挽救超长整数
所以——别对身份证、订单号、手机号这类字段用 float_format,它们根本就不是浮点数。
终极保险:用 csv.writer 手动控制每一行输出
当 pandas 的抽象层开始干扰数据本质时,退回到标准库是最可靠的。尤其适合字段混合了长数字、空值、特殊字符的场景:
- 用
csv.writer配合quoting=csv.QUOTE_MINIMAL或QUOTE_ALL - 确保所有待写入字段提前转成
str,包括None→'' - 跳过 pandas 的类型推断、索引、header 自动处理等潜在干扰点
示例:
import csv
rows = [['id', 'name'], ['12345678901234567890123', 'Alice']]
with open('safe.csv', 'w', newline='') as f:
writer = csv.writer(f, quoting=csv.QUOTE_ALL)
writer.writerows(rows)
真正容易被忽略的点是:问题往往不出在“怎么写”,而出在“怎么读”。只要上游读取时没用 dtype=str,后续所有格式控制都只是在补救一个已经发生的精度丢失。


















