如何在Polars中基于日期范围将低频数据合并填充到高频DataFrame?
使用Polars实现低频数据填充到高频表的方案
针对你的需求——将表1(低频数据)中日期范围匹配的行填充到表2(高频数据),同时保持数据类型一致,以下是高效的Polars实现步骤:
核心思路
通过条件左连接关联两张表,匹配type相同且表2的event_date落在表1的start_date至end_date范围内的记录,再处理可能的重复匹配,最后合并列并保证数据类型一致。
完整代码实现
import polars as pl # 假设df1是表1(低频数据),df2是表2(高频数据) # 可选:为type列建立索引,加速连接(千万级数据推荐) df1 = df1.set_index("type") df2 = df2.set_index("type") # 1. 条件左连接,匹配type和日期范围 joined = df2.join( df1, on="type", how="left", condition=(pl.col("event_date") >= pl.col("start_date")) & (pl.col("event_date") <= pl.col("end_date")) ) # 2. 处理重复匹配:每个type+event_date只保留一条匹配结果(这里按end_date降序取最新范围) result = joined.with_columns( pl.row_number().over(["type", "event_date"]).alias("rn") ).filter(pl.col("rn") == 1).drop("rn", "start_date", "end_date") # 3. 合并rating列:用表1的值填充表2的空值(若需直接替换则跳过此步,直接重命名) result = result.with_columns( pl.coalesce(pl.col("rating1_right"), pl.col("rating1_left")).alias("rating1"), pl.coalesce(pl.col("rating2_right"), pl.col("rating2_left")).alias("rating2") ).drop("rating1_left", "rating1_right", "rating2_left", "rating2_right") # 4. 整理列顺序(可选,按需调整) result = result.select( "type", "event_date", "year", "qtr", "rating1", "rating2", "rating3" )
关键细节说明
- 数据类型一致性:Polars在连接时会自动保留原表的数据类型,表1的
year(i16)、qtr(i8)等类型会直接继承到结果表中,无需额外转换。 - 性能优化:提前为
type列建立索引,能大幅提升千万级数据量下的连接速度;条件连接避免了全量交叉连接,确保内存和计算效率。 - 重复匹配处理:如果一个高频日期匹配到多个低频范围,代码中通过
row_number()按type+event_date分组取第一行,可根据业务需求调整排序逻辑(比如按start_date升序取最早范围)。 - 列填充逻辑:
coalesce函数会优先使用表1的非空值填充表2的空值,若表2已有值则保留;若需要直接用表1的值覆盖表2,可替换为直接重命名列:result = result.rename( {"rating1_right": "rating1", "rating2_right": "rating2"} ).drop("rating1_left", "rating2_left")
内容的提问来源于stack exchange,提问作者Young Eddie
相关产品推荐
相关产品推荐

