易君召
发布于 2026-08-06 / 作者:易君召 / 2 阅读
0

数据分析高效处理 CSV 文件

CSV 是数据分析最常用文本格式,痛点:大文件内存溢出、编码乱码、格式脏数据、读写慢、重复 IO。下面分 Python (Pandas / 原生 csv)、命令行工具、性能选型、最佳实践、大文件方案,覆盖小文件到 GB 级超大 CSV。

一、Pandas(日常数据分析首选)

1. 基础读取优化

python

运行

import pandas as pd

# 基础高效读取
df = pd.read_csv(
    "data.csv",
    usecols=["col1","col2"],        # 只读取需要列,大幅降内存
    dtype={"id":"int32","value":"float32"}, # 指定类型,避免object膨胀
    parse_dates=["dt"],             # 直接解析日期
    low_memory=False,               # 关闭按行推断类型,消除警告
    encoding="utf-8-sig",           # 解决BOM乱码;gbk用于中文windows导出csv
    na_values=["","NA","-"],        # 指定空值标记
)

关键:指定 dtype + usecols,这两个是小投入大收益,很多 CSV 内存爆炸就是全部读成 object 类型。

2. 大文件分批读取(不一次性加载全量到内存)

chunksize 返回迭代器,逐块处理,适合 GB 级 csv

python

运行

chunk_iter = pd.read_csv("big.csv", chunksize=100_000)
for chunk in chunk_iter:
    # 每一块做过滤、聚合、写入,不要全部拼接成大df
    res = chunk[chunk["amount"]>0]
    res.to_csv("filter_out.csv", mode="a", header=False, index=False)

注意:第一次写入写header=True,后续追加header=False

3. 高效写出 CSV

python

运行

df.to_csv(
    "out.csv",
    index=False,            # 不输出索引列,绝大多数场景关闭
    encoding="utf-8-sig",
    float_format="%.4f",    # 控制浮点数,减少文件体积
)

二、Python 内置 csv 模块(超轻量,内存极低)

适合不希望 pandas 依赖、流式逐行处理,不把整个表格放入内存。

python

运行

import csv

with open("data.csv","r",encoding="utf-8-sig") as f_in, open("out.csv","w",newline="",encoding="utf-8-sig") as f_out:
    reader = csv.DictReader(f_in)
    writer = csv.DictWriter(f_out, fieldnames=reader.fieldnames)
    writer.writeheader()
    for row in reader:
        # 逐行处理,内存只存一行
        if int(row["score"]) > 60:
            writer.writerow(row)

newline="" 是 windows 下 csv 标准写法,防止多出空行。

三、超大 CSV:突破 Pandas 内存限制方案对比

方案

适用场景

优点

缺点

pandas + chunksize

GB 级,需要 pandas 分析逻辑

复用 pandas 语法

不能做跨块复杂 join

Dask

几十 GB 级别,类 pandas API

并行,内存友好

部分 API 不完整

Polars

高性能现代库,CSV 读写极强

速度远快 pandas,内存占用低

新库,生态略小

命令行工具 awk/csvkit

简单过滤、统计、抽取列

无需 python,速度极快

复杂分析不方便

Polars 示例(强烈推荐现代高性能方案)

python

运行

import polars as pl

df = pl.read_csv(
    "big.csv",
    columns=["col1","col2"],
    dtypes={"id":pl.Int32},
    batch_size=100_000
)
# 惰性模式,超大数据不加载全部到内存
q = pl.scan_csv("big.csv").filter(pl.col("val")>100).select(["col1","col2"])
df_out = q.collect()
df_out.write_csv("result.csv")

四、Linux/macOS 命令行快速处理 CSV(不用写代码)

csvkit 工具集(专门处理 csv)

bash

# 查看前5行
csvlook data.csv | head -n5
# 只提取指定列
csvcut -c name,amount data.csv > subset.csv
# 过滤
csvgrep -c amount -r "^[1-9]" data.csv

awk 原生,适合巨型 csv

bash

# 打印第2、3列,跳过表头
awk -F ',' 'NR>1{print $2","$3}' data.csv > out.csv

五、常见坑与最佳实践

  1. 编码问题

    • Windows Excel 导出 csv:编码是gbk;保存带 BOM 的 utf8 用utf‑8‑sig

  2. 引号、换行在单元格内:不要自己 split 逗号!必须用 csv 解析库 (pandas/csv/polars),手工分割会破坏带逗号的字段。

  3. 数据类型陷阱:数字混杂文本会被识别为 object,内存暴涨;提前指定 dtype

  4. 不要反复读写 CSV:多次分析场景,读完转 parquet/feather,后续分析速度提升数倍。

    python

    运行

    df.to_parquet("data.parquet")
    df = pd.read_parquet("data.parquet")
    

    CSV 是交换格式,不是中间计算存储格式。中间计算优先用 parquet。

  5. 处理损坏 CSV:pandas 参数

    python

    运行

    pd.read_csv("bad.csv", on_bad_lines="skip") # 跳过格式错误行
    

六、选型总结

  1. 小文件 (<1GB):直接 Pandas,指定 dtype/usecols;

  2. 大文件 1‑10GB:pandas chunksize 或者 Polars scan_csv 惰性加载;

  3. 超大数据 10GB+:Dask / Polars;

  4. 简单过滤抽取、服务器无 Python 环境:awk、csvkit;

  5. 中间计算结果:导出 Parquet,避免反复读写 CSV。


原文链接 https://www.yijunzhao.cn/archives/efficient-csv-file-processing-data-analysis-guide

欢迎访问 小易撩挨踢

https://www.yijunzhao.cn/