预处理大CSV文件是加载前必须做的减法:用split切分、csvcut/cut删列、iconv转编码、mlr过滤,避免内存溢出。
用 pandas.read_csv 前先切分大文件,别硬扛 5GB CSV
直接 read_csv 加载几十 gb 的原始 csv,内存爆掉、卡死、甚至触发系统 oom killer 是常态。预处理不是“锦上添花”,是加载前必须做的减法。
核心思路:不求一次读完,只求把脏数据、无用列、超长行提前筛掉,让真正进内存的数据量降一个数量级。
- 用
split -l 1000000 bigfile.csv chunk_拆成百万行一组的文件,比 Python 逐行读更快更稳 - 拆完立刻用
head -n 1 chunk_00 | wc -c看首行字节数,确认是否含 BOM 或异常空格 —— 这些会导致后续read_csv解析错位 - 避免用
sed或awk做复杂字段替换(如含逗号的 quoted 字段),容易破坏 CSV 结构;简单清洗用csvformat -D '|' -t(来自csvkit)转成管道分隔再处理更安全
删列比删行更省时间,优先用 cut 和 csvcut
很多超大 CSV 里 70% 列根本不用,但 read_csv(usecols=[...]) 是在 Pandas 层过滤,意味着整行仍要解析、构造临时 list、再丢弃 —— 白耗 CPU 和内存。
真实提速点在 IO 层就砍掉不需要的列:
- 已知列名且稳定:用
csvcut -c "id,name,amount" input.csv > cleaned.csv - 只有列序号(比如只要第 1、3、7 列):用
cut -d, -f1,3,7 input.csv > cleaned.csv,注意-d,后不能有空格 - 如果原始 CSV 有双引号包裹字段(如
"Smith, John","2023-01-01"),cut会切错 —— 此时必须用csvcut,它懂 RFC 4180 规则
iconv 转编码比 Python open(encoding=...) 更快更准
常见错误:UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0 —— 实际是文件带 BOM 的 UTF-16 或 GBK 编码。Pandas 默认按 UTF-8 解,失败后回退慢,还可能静默乱码。
使用 qbo-mileage CLI 及用户凭证,从 Airtable、Outlook 或 Google Calendar 记录生成 QuickBooks Online 里程 CSV 文件。
预处理阶段就明确编码,一劳永逸:
- 先用
file -i input.csv或enca -L zh input.csv猜测编码(别全信,重点看charset=输出) - 确认是 GBK 后,用
iconv -f GBK -t UTF-8//IGNORE input.csv > utf8.csv,//IGNORE会跳过无法转换的字节,比 Python 的errors='replace'更少污染数据 - 别用
dos2unix处理换行 —— 它只改为,对编码无效;且某些 CSV 解析器(如 DuckDB)反而要求严格 CRLF
用 mlr(Miller)做条件过滤,比 awk 更稳
需要保留“金额 > 1000 且状态为 active”的行?别写 Python 脚本循环 —— 预处理阶段用流式工具更轻量。
mlr 是专为结构化文本设计的,支持 CSV/TSV/TJSON,语法接近 SQL,且能正确处理 quoted 字段:
- 过滤 + 类型转换一步到位:
mlr --csv filter '$amount > 1000 && $status == "active"' then cut -f id,amount input.csv > filtered.csv - 自动类型推断:加
--implicit-csv-header可以不依赖首行标题,适合 header 残缺的脏数据 - 注意:默认不校验数值格式,
$amount若含"N/A"会被当字符串比较;需先fillna或用if ($amount =~ "^\d+\.?\d*$", $amount, null)清洗
真正难的不是写对一行命令,而是搞清原始数据里到底有多少种隐式格式 —— 时间字段混着 2023/01/01、01-JAN-2023、epoch ms,这种没法靠通用工具一步解决,得先抽样统计分布,再决定是统一转 ISO8601 还是留到 Pandas 里用 pd.to_datetime(errors='coerce') 处理。










