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

如何用Python结合Dask快速读取大型XLSB文件?

快速读取大型XLSB文件的可行方案

一、修正Dask的使用方式(真正实现并行)

你的现有代码没有发挥Dask的并行能力——所有文件的读取逻辑被塞进一个delayed函数里,Dask只会单线程执行这个函数,速度自然和直接用pyxlsb没区别。正确的做法是给每个文件(或每个sheet)单独创建delayed任务,让Dask并行处理,最后合并为Dask DataFrame。

示例代码:

import dask.dataframe as dd
from dask.delayed import delayed
import pyxlsb
import pandas as pd

def read_single_xlsb(file_path):
    # 读取单个XLSB文件的所有sheet并合并
    data_frames = []
    with pyxlsb.open_workbook(file_path) as wb:
        for sheet_name in wb.sheet_names():
            with wb.get_sheet(sheet_name) as sheet:
                # 将sheet数据转为DataFrame
                df = pd.DataFrame(sheet.rows(values_only=True))
                # 第一行设为列名(有表头时用)
                df.columns = df.iloc[0]
                df = df[1:]
                data_frames.append(df)
    return pd.concat(data_frames, ignore_index=True)

# 替换为你的文件路径列表
file_list = ["file1.xlsb", "file2.xlsb", ...]

# 为每个文件创建独立的delayed任务
delayed_dfs = [delayed(read_single_xlsb)(f) for f in file_list]

# 转换为Dask DataFrame
ddf = dd.from_delayed(delayed_dfs)

# 执行计算(或做后续数据操作)
result = ddf.compute()

二、用多进程并行读取(轻量高效)

如果觉得Dask配置复杂,可以直接用Python标准库的concurrent.futures实现多进程读取,绕过Dask的额外开销,适合单文件多sheet或多文件场景。

示例代码:

import pyxlsb
import pandas as pd
from concurrent.futures import ProcessPoolExecutor

def read_sheet(file_path, sheet_name):
    with pyxlsb.open_workbook(file_path) as wb:
        with wb.get_sheet(sheet_name) as sheet:
            df = pd.DataFrame(sheet.rows(values_only=True))
            df.columns = df.iloc[0]
            return df[1:]

def read_xlsb_parallel(file_path):
    with pyxlsb.open_workbook(file_path) as wb:
        sheet_names = wb.sheet_names()
    
    # 用进程池并行读取每个sheet
    with ProcessPoolExecutor() as executor:
        futures = [executor.submit(read_sheet, file_path, name) for name in sheet_names]
        dfs = [future.result() for future in futures]
    
    return pd.concat(dfs, ignore_index=True)

# 读取单个大型XLSB文件
big_df = read_xlsb_parallel("large_file.xlsb")

三、减少读取的数据量(最直接的优化)

如果不需要全量数据,只读取必要的列或行,能大幅提升速度:

  • 跳过表头后的无用行(比如从指定行开始读取)
  • 只提取目标列(先匹配列索引,再筛选对应单元格)

示例:仅读取指定列

import pyxlsb
import pandas as pd

def read_selected_columns(file_path, sheet_name, target_cols):
    # 先获取表头,定位目标列的索引
    with pyxlsb.open_workbook(file_path) as wb:
        with wb.get_sheet(sheet_name) as sheet:
            header = next(sheet.rows(values_only=True))
            col_indices = [i for i, col in enumerate(header) if col in target_cols]
    
    # 只读取目标列的数据
    data = []
    with pyxlsb.open_workbook(file_path) as wb:
        with wb.get_sheet(sheet_name) as sheet:
            for row in sheet.rows(values_only=True):
                filtered_row = [row[i] for i in col_indices]
                data.append(filtered_row)
    
    df = pd.DataFrame(data[1:], columns=target_cols)
    return df

# 读取"Sheet1"中的"ID"和"Value"列
df = read_selected_columns("large_file.xlsb", "Sheet1", ["ID", "Value"])

四、预转换为高效格式(长期优化)

如果需要反复读取该大型XLSB文件,建议一次性转换为Parquet或CSV格式——这类格式的读取速度比XLSB快一个数量级:

# 先用并行方法读取XLSB
big_df = read_xlsb_parallel("large_file.xlsb")
# 保存为Parquet(压缩率高、读取快)
big_df.to_parquet("large_file.parquet")
# 后续读取只需一行
import pandas as pd
df = pd.read_parquet("large_file.parquet")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 10:55:31