Python pandas按连续相同值顺序分组拼接日期区间
解决方案
你的代码存在3个核心问题,修正后即可得到正确结果:
- 连续分组的标记没有做累计计算,导致不同位置的同值段被错误合并
- 误用
transform方法,该方法返回与原表等长的结果,无法实现分组聚合缩容 - 仅对date列做计算,未保留number列,且未实现首尾日期取最值拼接区间的逻辑
完整可运行代码
import pandas as pd # 先将date列转换为日期类型,避免字符串排序/取最值出错 df['date'] = pd.to_datetime(df['date']) # 生成连续段分组ID:每当number和上一行值不同时,分组ID加1 df['segment_id'] = (df['number'] != df['number'].shift()).cumsum() # 按分组ID聚合,生成最终结果 result = df.groupby('segment_id', as_index=False).agg( number=('number', 'first'), date=('date', lambda col: f"{col.min().strftime('%Y-%m-%d')} to {col.max().strftime('%Y-%m-%d')}") )[['number', 'date']]
输出结果
执行代码后得到的result完全匹配预期格式:
number date 0 123456 2021-01-16 to 2021-01-18 1 98765 2021-01-19 to 2021-02-01 2 123456 2021-02-02 to 2021-02-11 3 7645323 2021-02-13 to 2021-02-17
关键逻辑说明
- 分组ID生成逻辑:
(df['number'] != df['number'].shift())会在每段连续相同number的第一行返回True,其余行返回False,做cumsum()累计求和后,每一段连续相同number的行会被分配到同一个唯一ID,实现顺序连续分组 - 聚合逻辑:同一段连续分组内的number值完全一致,直接取第一个值即可;日期列取最小值作为区间起点、最大值作为区间终点,按要求格式拼接即可
- 顺序保证:因为分组是按原表顺序生成的segment_id,聚合后结果顺序和原表中连续段出现的顺序完全一致
提示:如果你的date列本身就是
YYYY-MM-DD格式的字符串,由于该格式的字符串字典序与日期先后顺序完全一致,可以跳过pd.to_datetime的类型转换步骤,直接对字符串列取min/max即可得到正确的首尾日期。
内容的提问来源于stack exchange,提问作者Kirti Purohit
相关产品推荐
相关产品推荐

