如何先满足条件再将值列表插入Pandas DataFrame单元格?
从Pandas DataFrame提取符合条件的团队列表并匹配插入
初始数据结构
初始DataFrame(Table_1)如下:
| ID | Team Assigned | Date Team Start | Date Team End | Service Date |
|---|---|---|---|---|
| 23 | Red | 2022-09-01 | 2022-09-29 | 2022-08-15 |
| 23 | Blue | 2022-08-01 | 2022-09-15 | 2022-09-12 |
| 23 | Green | 2022-09-27 | 2022-09-30 | 2022-09-29 |
| 23 | Black | 2022-08-01 | 2022-08-17 | 2022-05-04 |
| 23 | Purple | 2022-08-15 | 2022-09-30 | 2022-08-17 |
| 07 | Blue | 2022-07-03 | 2022-09-30 | 2022-07-05 |
| 07 | Red | 2022-07-03 | 2022-07-05 | 2022-01-01 |
| 07 | Purple | 2022-05-01 | 2022-06-24 | 2022-05-15 |
需求说明
针对每个ID和对应的Service Date,筛选出同一ID下满足**Service Date处于Date Team Start和Date Team End之间**的所有团队,将这些团队去重后以逗号分隔的字符串形式插入对应行的新列Teams Involved中。
尝试的代码
以下代码能生成目标数据对象,但不知道如何将值插入原DataFrame对应单元格:
for id in df['ID']: a = df[(df['Service Date'] <= df['Date Team End']) & (df['Service Date'] >= df['Date Team Start'])] a = a.groupby(['case no', 'Service Date'])['Team Assigned'].apply(lambda x: list(np.unique(x)))
期望结果
最终想要得到的DataFrame如下:
| ID | Team Assigned | Date Team Start | Date Team End | Service Date | Teams Involved |
|---|---|---|---|---|---|
| 23 | Red | 2022-09-01 | 2022-09-29 | 2022-08-15 | Blue, Black, Purple |
| 23 | Blue | 2022-08-01 | 2022-09-15 | 2022-09-12 | Red, Blue, Purple |
| 23 | Green | 2022-09-27 | 2022-09-30 | 2022-09-29 | Red, Green, Purple |
| 23 | Black | 2022-08-01 | 2022-08-17 | 2022-08-01 | Blue, Black |
| 23 | Purple | 2022-08-15 | 2022-09-30 | 2022-08-17 | Blue, Black, Purple |
| 07 | Blue | 2022-07-03 | 2022-09-30 | 2022-07-05 | Blue, Red |
| 07 | Red | 2022-07-03 | 2022-07-05 | 2022-08-01 | Blue |
| 07 | Purple | 2022-05-01 | 2022-06-24 | 2022-05-15 | Purple |
临时解决方案(待验证)
我修改了代码生成新的DataFrame,再与原DataFrame合并:
for id in df['ID']: a = df[(df['Service Date'] <= df['Date Team End']) & (df['Service Date'] >= df['Date Team Start'])] a = pd.DataFrame(a.groupby(['ID', 'Service Date'])['Team Assigned'].apply(lambda x: list(np.unique(x)))).reset_index().rename(columns={'Team Assigned':'List of Teams'}) df2 = pd.merge(df, a, on=['ID', 'Service Date'], how='left')
但这个方法实现起来比较繁琐,希望有更简洁的方案。
优化解决方案
可以不用循环,直接通过分组处理实现,步骤如下:
- 先确保日期列是datetime类型(如果原数据不是的话):
df['Date Team Start'] = pd.to_datetime(df['Date Team Start']) df['Date Team End'] = pd.to_datetime(df['Date Team End']) df['Service Date'] = pd.to_datetime(df['Service Date'])
- 按ID分组,批量生成匹配的团队列表:
def get_involved_teams(group): # 对组内每个Service Date,筛选满足时间条件的团队 def match_teams(service_date): mask = (group['Date Team Start'] <= service_date) & (group['Date Team End'] >= service_date) teams = group.loc[mask, 'Team Assigned'].unique() return ', '.join(sorted(teams)) # 可选排序,让结果更整齐 group['Teams Involved'] = group['Service Date'].apply(match_teams) return group # 分组处理后直接得到结果 result_df = df.groupby('ID').apply(get_involved_teams).reset_index(drop=True)
这个方法直接在原DataFrame上添加新列,无需额外合并,逻辑更清晰,也避免了循环带来的效率问题。
内容的提问来源于stack exchange,提问作者brandooo23
相关产品推荐
相关产品推荐

