Pandas按Job分组聚合任务数据:修正Schedule值与列名优化
解决思路与代码实现
1. 修正Schedule值的填充逻辑
直接全局执行fillna(method='ffill')会错误填充job5、job6的schedule值,需针对性处理:
- 先标记每个job分组内处于
START与END之间的有效任务行 - 仅对有效任务行的schedule列做向前填充,job5、job6的非任务行(需保留None的行)不做填充
2. 按Job分组并聚合任务列
使用groupby结合自定义聚合逻辑,同时手动指定友好的聚合列名。
完整代码示例
假设初始DataFrame结构如下(模拟业务场景):
import pandas as pd data = { 'job': ['job1', 'job1', 'job1', 'job1', 'job5', 'job5', 'job6', 'job6'], 'task_type': [None, 'task', 'task', None, None, None, None, None], 'task': [None, 't1', 't2', None, None, None, None, None], 'task_name': [None, 'task1', 'task2', None, None, None, None, None], 'schedule': ['s1', None, None, None, None, None, None, None], 'flag': ['START', None, None, 'END', 'START', 'END', 'START', 'END'] } df = pd.DataFrame(data)
步骤1:标记有效任务区间并填充schedule
# 按job分组,标记组内START到END之间的有效任务行 df['is_valid_task'] = df.groupby('job')['flag'].transform( lambda x: x.eq('START').cumsum() - x.eq('END').cumsum() > 0 ) # 仅对有效任务行的schedule做向前填充,其余行保留原值 df['schedule'] = df.apply( lambda row: row['schedule'] if not row['is_valid_task'] else df.loc[:row.name, 'schedule'].ffill().iloc[-1], axis=1 )
步骤2:分组聚合并设置友好列名
# 定义聚合规则:仅聚合非空值为列表,schedule取分组内唯一有效值(无则留None) agg_rules = { 'task_type': lambda x: x[x.notna()].tolist(), 'task': lambda x: x[x.notna()].tolist(), 'task_name': lambda x: x[x.notna()].tolist(), 'schedule': lambda x: x.unique()[0] if len(x.dropna().unique()) == 1 else None } # 分组聚合后重命名列名 result = df.groupby('job').agg(agg_rules).rename(columns={ 'task_type': 'task_type_list', 'task': 'task_list', 'task_name': 'task_name_list', 'schedule': 'schedule_info' }).reset_index()
关键说明
- job5、job6因无有效任务行,聚合后的task类列表为空,schedule值保留原None
- 通过
rename直接设置业务友好的列名,避免默认聚合列名的生硬感 - 有效区间标记确保仅处理START与END之间的任务行,不会误填充无关行的schedule
内容的提问来源于stack exchange,提问作者Mark
相关产品推荐
相关产品推荐

