如何利用Polars高效加载多CSV文件并添加产品编码列?
问题描述
我有多个结构相同的CSV文件:data_product_1.csv、data_product_2.csv、data_product_3.csv等。我知道可以用以下Polars代码把所有数据拼接成一个DataFrame:
import polars as pl df = pl.read_csv("data_*.csv")
但我希望在最终的DataFrame中新增一列product_code,其值为对应文件中的产品名称(比如从文件名里提取product_1这类标识),示例结果如下:
| 日期 | 数值 | product_code |
|---|---|---|
| 2000-01-01 | 1 | product_1 |
| 2000-01-02 | 2 | product_1 |
| 2000-01-01 | 3 | product_2 |
| 2000-01-02 | 4 | product_2 |
| 2000-01-01 | 5 | product_3 |
我知道可以逐个加载文件、添加列后再拼接,但想知道有没有更能发挥Polars性能的方法。
高效解决方案
Polars的**延迟加载(Lazy API)**是发挥性能的关键,无需逐个加载后拼接,通过扫描文件+批量处理即可实现,步骤如下:
- 用
glob获取所有目标CSV文件的路径 - 对每个文件路径,用
pl.scan_csv延迟读取,同时从文件名提取标识并添加为product_code列 - 用
pl.concat拼接所有延迟DataFrame,最后执行collect()得到结果
示例代码:
import polars as pl from glob import glob # 获取所有目标CSV文件 file_paths = glob("data_*.csv") # 批量处理每个文件:延迟读取 + 添加product_code列 lazy_dfs = [] for path in file_paths: # 从文件名提取product_code,例如从"data_product_1.csv"得到"product_1" product_code = path.split("_", 1)[1].rsplit(".", 1)[0] # 延迟读取并新增列 lazy_df = pl.scan_csv(path).with_columns(pl.lit(product_code).alias("product_code")) lazy_dfs.append(lazy_df) # 拼接并执行计算 final_df = pl.concat(lazy_dfs).collect()
性能优势说明
- 延迟加载(
scan_csv)不会一次性将所有数据加载到内存,适合处理大文件,Polars会自动优化整体处理流程 pl.concat处理延迟DataFrame时会进行并行优化,性能优于逐个加载后拼接的方式- 全程采用向量化操作,契合Polars的性能设计
如果偏好简洁写法,也可以用列表推导式:
import polars as pl from glob import glob final_df = pl.concat([ pl.scan_csv(path).with_columns( product_code=pl.lit(path.split("_", 1)[1].rsplit(".", 1)[0]) ) for path in glob("data_*.csv") ]).collect()
内容的提问来源于stack exchange,提问作者Roberto Landi
相关产品推荐
相关产品推荐

