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

如何比列表推导式更快将多份CSV转为Polars DataFrame?

高效批量读取Google Drive中CSV文件到Polars DataFrame的方案

核心问题分析

单线程逐个读取大量CSV文件,加上Google Drive的网络IO延迟,是导致耗时超30分钟的主要原因。以下是几个高效且Pythonic的解决方案:


方案1:多线程并行读取(IO密集型任务最优)

读取文件属于IO密集型操作,使用线程池可以同时处理多个文件的读取请求,大幅减少等待IO的时间。

from concurrent.futures import ThreadPoolExecutor
import polars as pl

def read_sim_csv(path):
    return pl.read_csv(path, schema_overrides={"X0.6": pl.Float64})

def read_ens_csv(path):
    return pl.read_csv(path, schema_overrides={"ridge_reg": pl.Float64})

# 线程池大小根据Colab资源调整,建议10-20
with ThreadPoolExecutor(max_workers=15) as executor:
    bdsim = list(executor.map(read_sim_csv, simpaths))
    bdens = list(executor.map(read_ens_csv, enspaths))

方案2:先复制到本地临时磁盘再读取

Colab本地磁盘的读写速度远高于Google Drive的网络IO,先批量复制文件到本地再读取,能显著降低IO延迟影响。

import os
from concurrent.futures import ThreadPoolExecutor
import polars as pl

# 创建本地临时目录
temp_sim_dir = "/tmp/sim_csvs"
temp_ens_dir = "/tmp/ens_csvs"
os.makedirs(temp_sim_dir, exist_ok=True)
os.makedirs(temp_ens_dir, exist_ok=True)

# 批量复制Drive文件到本地
def copy_to_local(src_path, dest_dir):
    dest_path = os.path.join(dest_dir, os.path.basename(src_path))
    !cp "$src_path" "$dest_path"
    return dest_path

# 并行复制
with ThreadPoolExecutor(max_workers=15) as executor:
    local_sim_paths = list(executor.map(lambda p: copy_to_local(p, temp_sim_dir), simpaths))
    local_ens_paths = list(executor.map(lambda p: copy_to_local(p, temp_ens_dir), enspaths))

# 从本地读取文件
bdsim = [pl.read_csv(p, schema_overrides={"X0.6": pl.Float64}) for p in local_sim_paths]
bdens = [pl.read_csv(p, schema_overrides={"ridge_reg": pl.Float64}) for p in local_ens_paths]

注意:本地临时目录的文件会在Colab会话结束后被删除,若需保留需复制回Google Drive。


方案3:延迟加载+合并(若最终需合并为单个DataFrame)

如果你的目标是将所有文件合并成单个DataFrame,直接使用Polars的scan_csv延迟加载+concat合并,能进一步优化性能,减少内存开销。

import polars as pl

# 合并所有sim文件为单个DataFrame
combined_sim = pl.concat([
    pl.scan_csv(p, schema_overrides={"X0.6": pl.Float64}) 
    for p in simpaths
]).collect()

# 合并所有ens文件为单个DataFrame
combined_ens = pl.concat([
    pl.scan_csv(p, schema_overrides={"ridge_reg": pl.Float64}) 
    for p in enspaths
]).collect()

额外优化建议

  • 若CSV文件格式统一,定义完整的schema而非仅覆盖单个字段,避免Polars自动推断字段类型的开销。例如:
    sim_schema = {"X0.6": pl.Float64, "col1": pl.Int32, "col2": pl.String}
    bdsim = [pl.read_csv(p, schema=sim_schema) for p in local_sim_paths]
    
  • 调整线程池max_workers参数,避免过度占用Colab资源,10-20是比较稳妥的范围。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 03:46:19