如何在Polars中实现按日期偏移(Shift by Date)获取前序日期值?
实现Polars按日期偏移(Shift by Date)获取前一个可用日期的k值
要实现按实际存在的前一个日期而非固定行数偏移来获取对应k值,核心思路是先统一每个日期的k值,再按日期排序后偏移,最后将结果广播回原数据的所有行。以下是两种简洁的实现方式:
方法一:使用临时映射表Join(直观易懂)
- 提取每个日期与对应k值的唯一映射关系(因同一日期的k值完全相同)
- 对映射表按日期排序,用
shift(1)获取前一个日期的k值 - 将映射表关联回原DataFrame,完成列填充
import polars as pl import numpy as np import datetime # 你的原始代码(保持不变) np.random.seed(1) df = (pl .DataFrame(dict( dt=np.random.randint(datetime.datetime(2023, 1, 1).timestamp(), datetime.datetime(2023, 1, 31).timestamp(), 100) )) .select( pl.from_epoch('dt').sort() ) .filter( (pl.col('dt').dt.day().cos() * 17).floor() % 3 == 0 ) .pipe(lambda df: df.with_columns( j=pl.lit(np.random.randint(10, 99, df.height)), )) .with_columns( k=pl.col('j').last().over(pl.col('dt').dt.date()), ) ) # 步骤1:生成日期-k的唯一映射表 date_k_map = df.select( pl.col('dt').dt.date().alias('date'), pl.col('k') ).unique() # 步骤2:按日期排序并获取前一个日期的k值 date_k_map = date_k_map.sort('date').with_columns( prev_k=pl.col('k').shift(1) ) # 步骤3:关联回原DataFrame,得到l列 df = df.join( date_k_map, left_on=pl.col('dt').dt.date(), right_on='date', how='left' ).drop('date').rename({'prev_k': 'l'}) print(df.head())
方法二:使用窗口函数链式调用(更简洁)
利用Polars的窗口函数特性,直接在原DataFrame中完成计算,无需额外生成映射表:
# 在你的原始df基础上添加l列 df = df.with_columns( l=pl.col('k') # 统一同一日期的k值(取第一个即可,因所有行k相同) .first().over(pl.col('dt').dt.date()) # 按日期全局排序,保证偏移顺序正确 .sort_by(pl.col('dt').dt.date()) # 偏移一行,得到前一个日期的k值 .shift(1) # 将偏移结果广播回同一日期的所有行 .over(pl.col('dt').dt.date()) )
关键说明
- 普通
shift(1)仅按行偏移,若同一日期有多行,会错误取到同一日期内上一行的k值;而上述方法先统一每个日期的k值,再按日期维度排序偏移,确保取到的是前一个完整可用日期的k值。 - 两种方法最终效果一致:第一个出现的日期的
l列为null,后续每个日期的l列均为前一个存在日期的k值。
内容的提问来源于stack exchange,提问作者levant pied
相关产品推荐
相关产品推荐

