如何用DuckDB处理CSV生成两个Polars DataFrame并避免重复计算?
解决方案
直接给结论:优先选择先生成完整的Polars DataFrame再拆分的方案,这是最直接高效避免重复计算的方式。
为什么不推荐两次独立查询?
两次查询会重复执行两个核心操作:
- 读取
my_data.csv文件两次 - 重复计算
avg(value)的滑动窗口统计
数据量小的时候差异不明显,但数据量大时会明显浪费IO和计算资源。
先生成完整DF再拆分的优势
只需要一次文件读取和窗口函数计算,后续用Polars的filter拆分是内存内的轻量操作,几乎没有额外开销,代码也更简洁易维护:
import polars as pl from datetime import date import duckdb # 一次性完成读取和预处理,得到完整Polars DataFrame data = duckdb.sql(""" select *, avg(value) over (order by date rows between 2 preceding and current row) as rolling_avg from read_csv('my_data.csv') """).pl() # 拆分训练集和验证集 train = data.filter(pl.col('date') < date(2020, 1, 4)) val = data.filter(pl.col('date') >= date(2020, 1, 4))
有没有在DuckDB内一次性生成两个数据集的方式?
也可以在DuckDB中先把预处理后的数据临时存储,再分别查询导出,但本质和上面的方案效率差不多,代码反而更繁琐,比如:
# 在DuckDB中创建临时表存储预处理结果 duckdb.sql(""" create temp table processed_data as select *, avg(value) over (order by date rows between 2 preceding and current row) as rolling_avg from read_csv('my_data.csv') """) # 分别查询得到训练集和验证集 train = duckdb.sql("select * from processed_data where date < make_date(2020,1,4)").pl() val = duckdb.sql("select * from processed_data where date >= make_date(2020,1,4)").pl()
这种方式同样避免了重复计算,但需要额外创建临时表,不如直接用Polars拆分来得简洁直观。
总结下来,先导出完整预处理后的Polars DataFrame再拆分是最优选择,兼顾效率和代码可读性。
内容的提问来源于stack exchange,提问作者ignoring_gravity
相关产品推荐
相关产品推荐

