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

pandas使用chunksize读取大文件时如何直接跳转到指定chunk处理

解决方案

你遇到的耗时本质是pandas迭代遍历前499个chunk时,会将所有行解析为DataFrame对象,哪怕你没有用到这些数据也会产生大量解析开销。pandas原生没有提供直接切片跳转到指定chunk的能力,因为CSV是无固定偏移索引的文本格式,无法直接计算第N个chunk的字节位置,以下是三种可行的解决方案:

方案1:预生成行偏移索引(最优,一次生成永久使用)

首次读取文件时生成每个chunk对应的字节偏移量索引并存储,后续读取指定chunk时可以直接通过文件指针跳转定位,完全跳过前面行的解析开销,速度最快。

第一步:生成偏移量索引(仅需执行一次)

import pandas as pd
import pickle

chunk_size = 100000
file_path = "/path/to/file/file.TXT"
offset_index = {}

with open(file_path, "rb") as f:
    # 读取表头
    header = f.readline()
    # 第1个chunk对应索引0的起始偏移
    offset_index[0] = f.tell()
    chunk_idx = 1
    line_count = 0
    while line := f.readline():
        line_count += 1
        if line_count == chunk_size:
            offset_index[chunk_idx] = f.tell()
            chunk_idx += 1
            line_count = 0

# 存储索引和表头信息
with open("file_offset_index.pkl", "wb") as f:
    pickle.dump((offset_index, header), f)

第二步:读取指定范围chunk

import pandas as pd
import pickle

chunk_size = 100000
file_path = "/path/to/file/file.TXT"
sep = "," # 替换为你实际的文件分隔符

# 加载预存的索引
with open("file_offset_index.pkl", "rb") as f:
    offset_index, header = pickle.load(f)
header_cols = header.decode().strip().split(sep)

# 遍历需要的第500到560个chunk(注意索引从0开始的话对应499到559,按需调整)
for chunk_idx in range(499, 560):
    with open(file_path, "rb") as f:
        # 跳转到对应chunk的起始字节位置
        f.seek(offset_index[chunk_idx])
        # 只读当前chunk的行数
        df = pd.read_csv(f, nrows=chunk_size, header=None, sep=sep, low_memory=False)
        df.columns = header_cols
    # 在此处执行业务逻辑

方案2:使用skiprows跳过前N行(无需预生成索引,速度中等)

如果不想预生成索引,可以直接通过skiprows参数跳过前面499个chunk的所有行,pandas会直接从指定行开始解析,内部的行计数是纯字节扫描,远快于解析为DataFrame的开销,比你原有遍历的方式快很多。

import pandas as pd

chunk_size = 100000
# 跳过前499个chunk的行数,如有表头需注意调整偏移量,可先用小文件测试参数
skip_rows = 499 * chunk_size
# 只读需要的60个chunk的总行数
read_rows = 60 * chunk_size

df_iter = pd.read_csv(
    "/path/to/file/file.TXT",
    chunksize=chunk_size,
    low_memory=False,
    skiprows=skip_rows,
    nrows=read_rows
)

for df_ia in df_iter:
    # 直接获取到第500到560个chunk的内容,无需判断索引
    # 在此处执行业务逻辑

方案3:使用itertools.islice简化写法(仅简化代码,速度无提升)

如果接受原有遍历速度,只是想要类似切片的简洁写法,可以用itertools.islice对迭代器做切片,本质还是会遍历前面的499个chunk并丢弃,速度和你原有代码一致。

import pandas as pd
from itertools import islice

chunk_iter = pd.read_csv(
    "/path/to/file/file.TXT",
    chunksize=100000,
    iterator=True,
    low_memory=False
)

# 切片取第499到559索引对应的chunk,即你需要的第500到560个chunk
for df_ia in islice(chunk_iter, 499, 560):
    # 在此处执行业务逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 15:54:01