最省事的方式是在 read_csv() 中用 usecols 参数直接选列,支持列名或索引列表,避免加载全量数据;二次筛选可用 filter() 或 df[[]];超大文件宜用 csv 模块流式处理。

用 pandas.read_csv() 读取时直接选列
如果目标只是保留某些字段(比如只要 "name" 和 "age"),最省事的方式是在读取阶段就筛掉无关列,避免加载整个大文件到内存。这在处理 GB 级 CSV 时尤其关键。
操作很简单:usecols 参数接受列名列表或列索引列表:
import pandas as pd
df = pd.read_csv("input.csv", usecols=["name", "age", "city"]) # 按列名选
# 或
df = pd.read_csv("input.csv", usecols=[0, 2, 4]) # 按位置选,从 0 开始
注意:usecols 会跳过未指定的列,连 header 都只保留你写的那些——所以输出文件的列顺序和你传入的列表顺序一致。如果原始 CSV 有空列或不规范分隔符,usecols 仍能工作,但建议先用 pd.read_csv("input.csv", nrows=1) 看一眼真实列名。
用 df.filter() 或 df[[]] 做二次筛选
读全量再过滤适合需要条件判断的场景,比如“只保留非空的 "email" 字段 + 同时要 "status" 为 "active" 的行”。这时先读全量,再用布尔索引或 filter()。
filter() 适合纯字段筛选,语法简洁:
df_filtered = df.filter(items=["name", "email", "signup_date"]) # 精确匹配列名 df_filtered = df.filter(regex="^id|_at$") # 正则匹配,如 "user_id"、"created_at"
更常用的是直接索引写法,它更直观且支持重排序:
-
df[["email", "name"]]—— 列顺序按你写的来 -
df.loc[:, ["email", "name"]]—— 明确声明只取列,避免链式赋值警告 - 别用
df.email单列取法做多列,它返回 Series,不能直接存多列
用 to_csv() 保存时控制格式细节
另存为新文件看似简单,但几个参数不设好容易出问题:
-
index=False—— 不写行号,否则第一列多出一列0,1,2... -
encoding="utf-8-sig"—— Windows 上用 Excel 打开中文不乱码(utf-8本身会导致首行出现“锘”) -
na_rep=""—— 把 NaN 替成空字符串,否则 Excel 里显示"nan" - 如果原 CSV 是用制表符或分号分隔的,记得传
sep="\t"或sep=";",否则默认逗号可能解析错
示例:
df_filtered.to_csv("output.csv", index=False, encoding="utf-8-sig", na_rep="")
不用 pandas:用内置 csv 模块流式处理超大文件
当文件大到内存扛不住(比如 >500MB),或者你根本不想装 pandas,就得用标准库 csv 模块逐行读写。
关键点是:不能先读完再过滤,必须边读边写。示例中只保留 "id" 和 "score" 两列:
import csv
with open("input.csv") as f_in, open("output.csv", "w", newline="") as f_out:
reader = csv.DictReader(f_in)
writer = csv.DictWriter(f_out, fieldnames=["id", "score"])
writer.writeheader()
for row in reader:
# 只取需要的字段,自动丢弃其他键
writer.writerow({k: row[k] for k in ["id", "score"]})
注意:newline="" 必须传给 open(),否则 Windows 下每行多一个空行;DictWriter 要求输入字典的 key 必须严格等于 fieldnames,否则报 ValueError;如果原始 CSV 没 header,改用 csv.reader + 列索引取值。
这种写法没有内存压力,但没法做跨行逻辑(比如“取每组最大 score 的那行”),真要复杂逻辑,还是得上 pandas 或 dask。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











