最轻量筛选用query()或布尔索引;按列分组保存用groupby().apply();数值区间拆分用pd.cut()/pd.qcut();超大文件须分块读取处理。

用 query() 或布尔索引做条件筛选再分组
直接用 query() 或布尔索引是最轻量、最可控的方式,适合「按单个或几个字段的明确条件切出子集」。比如你有一张千万行的销售表,只想拆出 region == "华东" 且 status == "completed" 的部分,不要整个表进内存再处理。
常见错误是先 df[condition] 再反复调用 groupby(),其实可以一步到位:
df_east = df.query('region == "华东" and status == "completed"')
注意:query() 支持字符串表达式,变量要加 @ 前缀(如 @min_amount),比纯布尔索引更易读;但列名含空格或特殊字符时得用反引号,比如 `order id` > 1000。
用 groupby().apply() 拆成多个 DataFrame 并保存为文件
当条件是「按某列分组后各自保存」,比如按 year_month 拆成每月一个 CSV,groupby().apply() 比循环更安全——它天然避免索引错乱和重复写入问题。
立即学习“Python免费学习笔记(深入)”;
实操建议:
- 用
groupby('year_month', group_keys=False)避免多一层索引嵌套 - 在
apply()里直接调用to_csv(),别返回中间 DataFrame,否则全加载进内存 - 加
chunksize参数控制单次写入量,防止大分组卡死:例如df_group.to_csv(f"{year}_data.csv", chunksize=50000)
错误示例:for name, group in df.groupby('category'): group.to_csv(...) —— 看似直观,但遇到空分组会报 KeyError,且无法并发或加进度提示。
仅使用 Python 将 Claw Code 虚拟化框架与 OpenClaw 集成,提供 184 种工具和 200 多条命令,用于安全分析和代码质量...
用 pd.cut() 或 pd.qcut() 按数值区间条件拆分
数值型字段(如订单金额、用户停留时长)常需按范围切片,比如「0–100 元」「101–500 元」「501+ 元」。这时候别手写 df[(df['amt']>=0) & (df['amt'],容易漏边界、难维护。
pd.cut() 按固定间隔切,pd.qcut() 按分位数切,都返回分类型 Series,可直接用于 groupby:
df['amt_bin'] = pd.cut(df['amount'], bins=[0, 100, 500, float('inf')], labels=['low', 'mid', 'high'])
注意点:
-
right=True(默认)表示区间右闭,[0,100]包含 100;设right=False变成左闭 - 如果数据里有
NaN,cut()默认把它们标为NaN,后续groupby会自动丢弃,需提前用dropna=False保留 - 大表慎用
qcut(..., duplicates='drop'),否则可能因重复值导致 bin 数量少于预期
内存超限?优先用 chunksize + 迭代处理
真正的大表(>5GB)根本没法一次性读进内存,硬拆只会触发 MemoryError。必须从读取阶段就分块。
正确姿势:
- 用
pd.read_csv(filename, chunksize=100000)返回可迭代对象,每次只拿 10 万行 - 对每个
chunk单独做条件过滤,满足就追加到对应文件(用mode='a')或缓存到列表(小分组才缓存) - 避免用
pd.concat([chunks])拼全量——这等于又把所有 chunk 加载进内存
容易被忽略的是文件写入竞争:多个 chunk 同时写同一文件会出错。要么加锁(复杂),要么改用 pathlib.Path(file).open('a') 手动控制句柄,或干脆每个 chunk 写临时文件,最后用系统命令合并。

















