Python:按Group分组对Name的起始日期前向填充(重复Name场景)
问题描述
原始数据
Index Date Group Name 0 Oct-10 A Sam 1 Oct-10 A Sam 2 Dec-12 A Sam 3 Dec-12 A Sam 4 May-13 A Peter 5 May-14 A Peter 6 May-15 A Chris 7 Apr-17 A Chris 8 Apr-17 A Sam 9 Jul-23 A Sam 10 Dec-12 B Peter 11 Dec-12 B Peter 12 May-13 B Peter 13 May-14 B Peter 14 Apr-18 B Sam 15 Jul-19 B Sam 16 Jul-20 B Sam 17 Jul-22 B Sam 18 Jul-23 B Sam
需求说明
按Group分组,为每个Name的连续出现段填充该段的起始日期:
- 例如Group A中,Sam首次连续出现(索引0-3)的
date2列统一填Oct-10;2017年4月再次连续出现时(索引8-9),date2列统一填Apr-17。
尝试的错误代码
for every group in df["Group"]: df["date2"] = (df["Date"].groupby(["Name"]).transform(lambda x: x.ffill()))
该代码未达到预期,原因是仅按Name分组,未考虑Group维度,也未区分Name的连续出现分段,导致所有同Name的行都会填充最早的日期,不符合连续段的要求。
期望输出
Index Date Group Name date2 0 Oct-10 A Sam Oct-10 1 Oct-10 A Sam Oct-10 2 Dec-12 A Sam Oct-10 3 Dec-12 A Sam Oct-10 4 May-13 A Peter May-13 5 May-14 A Peter May-13 6 May-15 A Chris May-15 7 Apr-17 A Chris May-15 8 Apr-17 A Sam Apr-17 9 Jul-23 A Sam Apr-17 10 Dec-12 B Peter Dec-12 11 Dec-12 B Peter Dec-12 12 May-13 B Peter Dec-12 13 May-14 B Peter Dec-12 14 Apr-18 B Sam Apr-18 15 Jul-19 B Sam Apr-18 16 Jul-20 B Sam Apr-18 17 Jul-22 B Sam Apr-18 18 Jul-23 B Sam Apr-18
解决方案
实现思路
- 按
Group分组,在每个组内识别Name的连续出现分段:通过对比当前行与上一行的Name,生成分段标识并累加得到唯一的分段ID。 - 按
Group+分段ID分组,提取每个分段的第一个Date作为该段所有行的date2值。
代码实现
import pandas as pd # 构造原始DataFrame(如果已有数据可跳过此步) data = { 'Date': ['Oct-10', 'Oct-10', 'Dec-12', 'Dec-12', 'May-13', 'May-14', 'May-15', 'Apr-17', 'Apr-17', 'Jul-23', 'Dec-12', 'Dec-12', 'May-13', 'May-14', 'Apr-18', 'Jul-19', 'Jul-20', 'Jul-22', 'Jul-23'], 'Group': ['A']*9 + ['B']*10, 'Name': ['Sam', 'Sam', 'Sam', 'Sam', 'Peter', 'Peter', 'Chris', 'Chris', 'Sam', 'Sam', 'Peter', 'Peter', 'Peter', 'Peter', 'Sam', 'Sam', 'Sam', 'Sam', 'Sam'] } df = pd.DataFrame(data) # 生成每个Group内Name的连续分段ID df['segment_id'] = df.groupby('Group')['Name'].apply(lambda x: (x != x.shift()).cumsum()) # 为每个分段填充起始日期 df['date2'] = df.groupby(['Group', 'segment_id'])['Date'].transform('first') # 可选:删除临时的segment_id列 df = df.drop('segment_id', axis=1) # 查看结果 print(df)
代码解释
(x != x.shift()).cumsum():在每个Group内,当当前行Name与上一行不同时返回True(数值1),否则返回False(数值0),累加后得到每个连续段的唯一ID,以此区分同一Name的非连续出现段。transform('first'):对Group+segment_id的组合分组,提取该组的第一个Date值,并填充到组内所有行的date2列,实现同一段内起始日期的统一填充。
内容的提问来源于stack exchange,提问作者sam
相关产品推荐
相关产品推荐

