Python实现起始与结束日期生成问题求助
问题:为每个ID和SUB ID计算起始/结束日期
我是Python新手,想要编写Python代码实现以下需求:
- 为每个
ID和SUB ID组,将对应的最早Extraction Date作为起始日期 - 当
Conditon met (Y/N)为Y时,将该行的Extraction Date作为结束日期;未满足条件的行结束日期填N/A
示例数据表
| ID | SUB ID | Extraction Date | Conditon met (Y/N) |
|---|---|---|---|
| 1 | x | 2023-01-02 | N |
| 1 | y | 2023-01-02 | N |
| 1 | x | 2023-02-15 | N |
| 2 | v | 2023-02-15 | N |
| 2 | z | 2023-02-15 | N |
| 1 | x | 2023-03-15 | Y |
| 2 | v | 2023-03-15 | Y |
我尝试过但未成功的代码
df['start date'] = df.groupby(['ID','SUB ID'], as_index = False)['Extraction Date'].transform(min).reset_index() df['start date'] = df.groupby(['ID','SUB ID'], as_index = False)['Extraction Date'].min() df['end date'] = df.query(Condition met (Y/N) == Y).groupby(['ID','SUB ID'], as_index = False)['Extraction Date'].transform(max).reset_index() df['end date'] = df.query(Condition met (Y/N) == Y).groupby(['ID','SUB ID'], as_index = False)['Extraction Date'].min()
期望结果
| ID | SUB ID | Extraction Date | Conditon met (Y/N) | Start Date | End Date |
|---|---|---|---|---|---|
| 1 | x | 2023-01-02 | N | 2023-01-02 | N/A |
| 1 | y | 2023-01-02 | N | 2023-01-02 | N/A |
| 1 | x | 2023-02-15 | N | 2023-01-02 | N/A |
| 2 | v | 2023-02-15 | N | 2023-02-15 | N/A |
| 2 | z | 2023-02-15 | N | 2023-02-15 | N/A |
| 1 | x | 2023-03-15 | Y | 2023-01-02 | 2023-03-15 |
| 2 | v | 2023-03-15 | Y | 2023-02-15 | 2023-03-15 |
解决方案
你的问题核心在于groupby使用方式错误、query语法不规范,以及结束日期的匹配逻辑问题。以下是可行代码:
import pandas as pd # 先将日期列转为datetime类型(确保后续日期计算正常) df['Extraction Date'] = pd.to_datetime(df['Extraction Date']) # 计算起始日期:用transform返回每个组的最小日期,保持原数据行数 df['Start Date'] = df.groupby(['ID', 'SUB ID'])['Extraction Date'].transform('min') # 计算结束日期:先提取条件为Y的行,按组取对应日期,再合并回原表 end_date_map = df[df['Conditon met (Y/N)'] == 'Y'].groupby(['ID', 'SUB ID'])['Extraction Date'].first() df['End Date'] = df.apply(lambda row: end_date_map.get((row['ID'], row['SUB ID']), 'N/A'), axis=1) # 如果需要将日期格式转为字符串(如原示例的YYYY-MM-DD),可添加: # df['Start Date'] = df['Start Date'].dt.strftime('%Y-%m-%d') # df['End Date'] = df['End Date'].apply(lambda x: x.strftime('%Y-%m-%d') if isinstance(x, pd.Timestamp) else x)
关键说明:
transform('min')会为每一行返回对应组的最小日期,完美匹配原数据的行数结构,避免直接赋值groupby结果导致的维度不匹配问题。- 先筛选条件为
Y的行,通过groupby+first()获取每个组的结束日期,再用apply匹配到原表,未匹配到的组自动填充N/A。
内容的提问来源于stack exchange,提问作者Ryuugiri
相关产品推荐
相关产品推荐

