如何在Polars中按分组首行日期计算日期差值?
解决方法
要实现需求,核心是按选手组合分组获取首次格斗日期,再计算当前日期与该日期的差值,具体步骤如下:
- 转换日期格式:先把
On列的字符串日期转成Polars可计算的日期类型,否则无法做日期差运算。 - 分组获取首次日期:用窗口函数
over,按Person和Fight with分组,提取每组的第一个日期。 - 计算日期间隔并格式化:用当前日期减去分组后的首次日期得到天数差,再转成
X Days的字符串格式。 - 整理输出结果:保留原表列,添加计算好的
Distance列,按需清理中间列。
完整代码如下:
import polars as pl df = pl.from_repr(""" ┌──────────┬────────────┬────────┐ │ Person ┆ Fight with ┆ On │ │ --- ┆ --- ┆ --- │ │ str ┆ str ┆ str │ ╞══════════╪════════════╪════════╡ │ A ┆ B ┆ 3 Jan │ │ A ┆ C ┆ 4 Jan │ │ A ┆ D ┆ 5 Jan │ │ A ┆ E ┆ 5 Jan │ │ A ┆ B ┆ 10 Jan │ │ A ┆ B ┆ 20 Jan │ │ A ┆ C ┆ 20 Jan │ └──────────┴────────────┴────────┘ """) result = ( df # 1. 转换字符串日期为日期类型,临时存为On_date列 .with_columns( pl.col("On").str.to_date("%d %b").alias("On_date") ) # 2. 按选手组合分组,获取每组的首次格斗日期 .with_columns( pl.col("On_date").first().over(["Person", "Fight with"]).alias("first_fight_date") ) # 3. 计算日期间隔,格式化为X Days的字符串 .with_columns( (pl.col("On_date") - pl.col("first_fight_date")) .dt.total_days() .cast(pl.Int32) .str.concat(" Days") .alias("Distance") ) # 4. 保留原列和Distance列,删除临时列 .select(["Person", "Fight with", "On", "Distance"]) ) print(result)
代码解释
str.to_date("%d %b"):把3 Jan这种格式的字符串转成日期,%d匹配日,%b匹配月份缩写(Jan/Feb等)。first().over(["Person", "Fight with"]):窗口函数,对每一行匹配其所属的Person+Fight with组,提取该组的第一个日期,确保每行都能拿到对应组的首次格斗日期,而非仅返回分组聚合结果。(On_date - first_fight_date).dt.total_days():计算两个日期的天数差,转成整数后拼接Days字符串,得到需求的格式。
运行后输出与期望结果一致:
┌────────┬────────────┬────────┬──────────┐ │ Person ┆ Fight with ┆ On ┆ Distance │ │ --- ┆ --- ┆ --- ┆ --- │ │ str ┆ str ┆ str ┆ str │ ╞════════╪════════════╪════════╪══════════╡ │ A ┆ B ┆ 3 Jan ┆ 0 Days │ │ A ┆ C ┆ 4 Jan ┆ 0 Days │ │ A ┆ D ┆ 5 Jan ┆ 0 Days │ │ A ┆ E ┆ 5 Jan ┆ 0 Days │ │ A ┆ B ┆ 10 Jan ┆ 7 Days │ │ A ┆ B ┆ 20 Jan ┆ 17 Days │ │ A ┆ C ┆ 20 Jan ┆ 16 Days │ └────────┴────────────┴────────┴──────────┘
内容的提问来源于stack exchange,提问作者user24758287
相关产品推荐
相关产品推荐

