读取超大csv必须加chunksize、usecols、dtype、low_memory=false四个参数,以分块读取、按需加载列、显式指定类型、禁用内存优化推断,避免内存溢出和io卡死。

读取超大CSV卡死或内存爆掉,pd.read_csv 必须加这四个参数
默认直接调用 pd.read_csv('data.csv') 加载几个GB的文件,大概率触发内存溢出或卡在IO上不动。根本原因是pandas会一次性把整张表读进内存、推断每列类型、构建完整DataFrame——对大文件来说纯属浪费。
实操建议:
- 用
chunksize分块读(返回TextFileReader迭代器),边读边处理,不囤积数据 - 显式指定
dtype,跳过类型推断(比如把一列全设为'category'或'int32',能省50%+内存) - 用
usecols只读需要的列,尤其避开长文本字段(如日志、JSON字符串) - 设
low_memory=False防止分块推断冲突报DtypeWarning——这不是警告,是pandas在悄悄改你数据类型
示例:
for chunk in pd.read_csv('big.csv', chunksize=50000, usecols=['user_id', 'event_time'], dtype={'user_id': 'uint32'}, low_memory=False):
process(chunk) # 自定义处理逻辑
日期列解析慢、格式错乱,parse_dates 和 date_parser 别混用
默认 parse_dates 会调用 dateutil.parser.parse,对百万行以上数据,慢到不可接受;更糟的是,如果某列里混了非法格式(如空值、'N/A'、时间戳秒级/毫秒级混用),它可能静默跳过或转成 NaT,后续分析就埋雷了。
实操建议:
- 优先用
parse_dates=['col_name']+infer_datetime_format=True(仅限标准格式如'2023-01-01'或'2023/01/01 12:34:56') - 非标格式(如
'Jan 1, 2023 12:34 PM')必须配date_parser,且要用lambda x: pd.to_datetime(x, format='...')显式指定format,别依赖自动推断 - 含时区或毫秒级时间戳,直接用
dtype='datetime64[ms]'+converters预处理,比parse_dates稳定
中文路径、乱码、分隔符异常,encoding 和 sep 不是猜出来的
Windows下保存的CSV常是 gbk 或 gb2312 编码,Linux/macOS生成的多为 utf-8-sig(带BOM)。直接用默认 encoding='utf-8' 读,轻则报 UnicodeDecodeError,重则中文变“”还继续跑——结果全错。
实操建议:
- 先用命令行确认编码:
file -i filename.csv(Linux/macOS)或chcp+ 记事本另存为看编码(Windows) - 常见编码优先试:
utf-8-sig→gbk→latin-1(后者不会报错,但中文会乱,可用来快速判断是否编码问题) - 分隔符不是只有逗号:
sep='\t'对TSV,sep='|'对管道分隔,sep=r'\s+'对多空格;若首行有BOM或空格,加skipinitialspace=True
读取后内存还是高?category、nullable int 和 string dtype 得手动切
即使用了 dtype,pandas默认仍可能把字符串列存成 object(即Python str指针数组),内存占用是 string 类型的2–3倍;分类字段(如省份、状态码)放 object 更是灾难。
实操建议:
- 固定取值少的字符串列(≤50个唯一值),强制设
dtype='category',内存降90%很常见 - 整数列含缺失值,别用默认
float64模拟,改用Int64(首字母大写,pandas nullable类型) - 纯文本列明确设
dtype='string'(pandas 1.0+),避免object引发的隐式转换和性能陷阱 - 读完立刻用
df.memory_usage(deep=True).sum()检查,别等跑完才发现内存翻倍
最易被忽略的一点:分块读取时,每块的 category 是独立编码的——合并前得用 pd.concat(..., ignore_index=True) 并重新 astype('category'),否则类别数会指数级膨胀。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











