You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优化Pandas读取大CSV文件速度并降低内存占用?

针对大型CSV读取优化与低内存适配的解决方案

一、优化read_csv读取速度

你的当前代码瓶颈主要来自engine='python'(多字符分隔符\x1D和skipfooter限制只能用Python引擎,而它比C引擎慢数倍),可从以下方向优化:

  1. 换用Polars库读取(优先推荐)
    Polars原生支持多字符分隔符,读取速度远快于Pandas,且内存效率更高,同时支持直接跳过首尾行:
import polars as pl
# 读取文件,跳过首行和末行,指定分隔符与全字符串类型
df = pl.read_csv(
    input_file,
    separator="\x1D",
    dtype=str,
    skip_rows=1,  # 跳过首行
    skip_footer=1,  # 跳过末行
    ignore_errors=True
)
# 如需后续用Pandas处理,可转换格式
df_pd = df.to_pandas()
  1. 预处理文件后用轻量化方式读取
    先用命令行工具(如sed)去掉首尾行,再用csv.reader处理多字符分隔符后转成DataFrame,速度比直接用Pandas Python引擎更快:
# 预处理:去掉第1行和最后1行,输出到临时文件
sed '1d;$d' input.csv > temp_cleaned.csv
import csv
import pandas as pd

with open('temp_cleaned.csv', 'r') as f:
    reader = csv.reader(f, delimiter='\x1D')
    header = next(reader)
    rows = list(reader)

df = pd.DataFrame(rows, columns=header, dtype=str)
  1. 启用PyArrow后端优化字符串存储
    如果必须用Pandas Python引擎,可开启dtype_backend='pyarrow'(需安装PyArrow库),用PyArrow的高效字符串类型替代默认的object类型,减少内存占用同时提升读取速度:
pd.read_csv(
    input_file,
    sep='\x1D',
    engine='python',
    skiprows=1,
    skipfooter=1,
    header=0,
    dtype=str,
    keep_default_na=False,
    dtype_backend='pyarrow'
)

二、低内存系统下的适配方案

  1. 用Polars替代Pandas
    Polars采用列式存储,内存占用通常仅为Pandas的30%-50%,且支持高效的join操作(交集),无需全量加载数据到内存:
import polars as pl

# 读取两个文件
df1 = pl.read_csv(
    "file1.csv",
    separator="\x1D",
    dtype=str,
    skip_rows=1,
    skip_footer=1
)
df2 = pl.read_csv(
    "file2.csv",
    separator="\x1D",
    dtype=str,
    skip_rows=1,
    skip_footer=1
)

# 基于交差列(示例为`key_col`)获取交集行
common_rows = df1.join(df2, on='key_col', how='inner')
# 如需Pandas格式,可转换
common_rows_pd = common_rows.to_pandas()
  1. 利用SQLite数据库处理交集
    将CSV分块导入内存数据库,通过SQL查询获取交集,无需全量加载数据到内存:
import sqlite3
import pandas as pd

# 连接内存SQLite数据库
conn = sqlite3.connect(':memory:')
chunk_size = 100000

# 分块导入第一个文件
for chunk in pd.read_csv(
    "file1.csv",
    sep='\x1D',
    engine='python',
    skiprows=1,
    skipfooter=1,
    header=0,
    dtype=str,
    keep_default_na=False,
    chunksize=chunk_size
):
    chunk.to_sql('table1', conn, if_exists='append', index=False)

# 分块导入第二个文件
for chunk in pd.read_csv(
    "file2.csv",
    sep='\x1D',
    engine='python',
    skiprows=1,
    skipfooter=1,
    header=0,
    dtype=str,
    keep_default_na=False,
    chunksize=chunk_size
):
    chunk.to_sql('table2', conn, if_exists='append', index=False)

# 查询交集(替换`key_col`为实际交差列)
query = """
SELECT * FROM table1
INNER JOIN table2 ON table1.key_col = table2.key_col
"""
common_rows = pd.read_sql(query, conn)
conn.close()
  1. 预计算交差列哈希,过滤后加载
    先读取第一个文件的交差列生成哈希集合,再分块读取第二个文件时只保留在集合内的行,大幅减少内存占用:
import pandas as pd

# 读取第一个文件的交差列(替换为实际交差列名)
df1_keys = pd.read_csv(
    "file1.csv",
    sep='\x1D',
    engine='python',
    skiprows=1,
    skipfooter=1,
    header=0,
    usecols=['key_col1', 'key_col2'],
    dtype=str,
    keep_default_na=False
)
# 生成哈希集合(用元组作为唯一键)
key_set = set(tuple(row) for row in df1_keys.values)

# 定义过滤函数
def filter_chunk(chunk):
    # 生成每行的交差列元组
    chunk['key_tuple'] = chunk[['key_col1', 'key_col2']].apply(tuple, axis=1)
    # 过滤出在集合内的行
    filtered = chunk[chunk['key_tuple'].isin(key_set)].drop('key_tuple', axis=1)
    return filtered

# 分块读取并过滤第二个文件
df2_filtered = pd.concat([
    filter_chunk(chunk) for chunk in pd.read_csv(
        "file2.csv",
        sep='\x1D',
        engine='python',
        skiprows=1,
        skipfooter=1,
        header=0,
        dtype=str,
        keep_default_na=False,
        chunksize=100000
    )
])

# 与第一个文件合并获取最终交集
common_rows = df1.merge(df2_filtered, on=['key_col1', 'key_col2'])

内容的提问来源于stack exchange,提问作者SpaceyBot

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 04:25:24