如何避免Pandas DataFrame中NaN/NULL值在csv.QUOTE_ALL后被引号包裹?
解决方法
1. 自定义CSV引用规则,精准处理NaN
如果必须用QUOTE_ALL包裹所有含特殊字符的字段,但不想让NaN被引号套住,可以自定义引用逻辑,让NaN输出为无引号的空字符串,其他字段正常加引号:
import csv import pandas as pd def custom_quote_rule(field): # 对NaN返回不引用,其他字段全引用 if pd.isna(field): return csv.QUOTE_NONE return csv.QUOTE_ALL df.to_csv( r"test.csv", index=False, sep='|', quoting=custom_quote_rule, na_rep='' )
2. 换用QUOTE_NONNUMERIC更省心
如果数据中需要加引号的只有字符串类型(带特殊字符/分隔符的内容都在字符串列),直接用csv.QUOTE_NONNUMERIC即可。它会自动给字符串字段套引号,数值、时间戳这类非字符串字段(包括NaN)会输出为无引号的空值,刚好适配PostgreSQL的类型要求:
import csv import pandas as pd df.to_csv( r"test.csv", index=False, sep='|', quoting=csv.QUOTE_NONNUMERIC, na_rep='' )
3. 跳过CSV,直接把DataFrame写入数据库
最省事的办法是绕开CSV文件,直接用Pandas把数据写入PostgreSQL,无需手动处理引号问题:
from sqlalchemy import create_engine import pandas as pd # 替换成你的数据库连接信息 engine = create_engine('postgresql://用户名:密码@主机:端口/数据库名') # 写入表,if_exists可选append(追加)、replace(替换)、fail(存在则报错) df.to_sql( name='目标表名', con=engine, if_exists='replace', index=False, method='multi' # 批量写入提速 )
4. 若必须用COPY命令的补救办法
如果已经生成了带引号空串的CSV,可在COPY命令里指定把空字符串识别为NULL:
COPY 目标表名 FROM '/文件路径/test.csv' DELIMITER '|' QUOTE '"' NULL '' CSV;
或者用命令行工具把CSV里的""替换成空(注意:如果有合法的""字符串值,请勿使用此方法):
sed -i 's/""/''/g' test.csv
内容的提问来源于stack exchange,提问作者Vikas Garud
相关产品推荐
相关产品推荐

