用 pandas.to_csv() 导出最稳,但需设 encoding='utf-8-sig' 防乱码、date_format 统一时间格式、na_rep='' 处理缺失值;大文件应分块或改用 Parquet;Excel 打开须走“数据→从文本/CSV”导入向导。
用 pandas.DataFrame.to_csv() 导出最稳,但默认行为容易丢数据
直接调用 to_csv() 看似简单,实际导出的 csv 常出现中文乱码、日期格式错乱、数值被科学计数法截断等问题——根本原因是默认编码和参数没对齐目标平台。
- Windows Excel 默认读取
utf-8-sig编码(带 BOM),而to_csv(encoding='utf-8')会出乱码;必须显式写成encoding='utf-8-sig' - 时间列如
datetime64类型不加处理会被转成带时区或纳秒级字符串,建议用date_format='%Y-%m-%d %H:%M:%S'统一格式 - 浮点数列如果含
NaN,默认导出为nan字符串,Excel 无法识别为缺失值;加na_rep=''更安全
示例:
df.to_csv('data.csv', encoding='utf-8-sig', date_format='%Y-%m-%d', na_rep='', index=False)
Mac / Linux 下用 csv.writer 手动控制更可靠
当 pandas 不在环境里,或需要精细控制每行字段(比如强制加引号、跳过空行),原生 csv.writer 反而更透明,尤其避免了 pandas 自动类型推断导致的数字前导零丢失(如工号 00123 变成 123)。
- 用
quoting=csv.QUOTE_NONNUMERIC或QUOTE_ALL保证字符串字段始终带引号,防止逗号、换行破坏结构 - 写入前把所有字段转成
str,并手动补零:str(val).zfill(5),绕过 pandas 的自动类型转换 - Unix 系统默认换行是
\n,但 Excel for Mac 要求\r\n;打开文件时务必用newline='',再由writer控制行结束符
示例:
with open('data.csv', 'w', newline='', encoding='utf-8-sig') as f:<br> writer = csv.writer(f, quoting=csv.QUOTE_ALL)<br> writer.writerow(['id', 'name'])<br> for row in data:<br> writer.writerow([str(row[0]).zfill(5), row[1]])
导出后打不开?先看 Excel 是不是在“数据”选项卡里点错了入口
双击 CSV 文件用 Excel 打开,常遇到中文全乱、小数点变逗号、日期全变成数字——这不是导出错了,是 Excel 没走「导入向导」,而是用系统区域设置硬解析。
- 正确做法:Excel 里点「数据」→「从文本/CSV」,选中文件,手动选
UTF-8编码,再点「加载」 - 如果必须双击打开,Windows 用户可临时改系统区域设置里的「Beta 版 UTF-8 支持」勾选状态(需重启资源管理器)
- Mac 用户无解,双击必然失败;只能靠「文件」→「打开」→ 选中 → 点「选项」里调编码
大文件(>100MB)别硬导 CSV,优先考虑 chunksize 分块或换 Parquet
用 to_csv() 一次性导出千万行以上数据,内存暴涨、磁盘 I/O 卡死、Python 进程假死——CSV 是纯文本,没压缩、没索引、没类型信息,纯靠字符串拼接。
- 分块导出:用
pandas.read_sql(..., chunksize=50000)配合循环to_csv(..., mode='a', header=False) - 跨平台又高效:导出
.parquet(用df.to_parquet('data.parquet', engine='pyarrow')),再让下游用 Python / R / DuckDB 读;比 CSV 小 3–5 倍,且保留类型和 null - 如果对方只认 CSV,就压缩:导出后用
gzip.open包一层,发.csv.gz,多数现代工具(包括 Excel Online)能直接解压读
真正麻烦的从来不是“怎么导出”,而是“对方用什么打开、在哪打开、有没有权限装新软件”。编码、换行、字段包裹、数据保真——每个细节都在跨平台时放大十倍。别信“默认就好”,多试一次编码,少修两小时表。

















