如何将按列存储多任务的Pandas DataFrame按任务拆分为多行
Pandas宽表转多行任务数据通用方案
直接使用Pandas内置的wide_to_long函数即可实现任意最大任务数k的通用转换,无需针对任务数做分支适配,具体实现如下:
步骤1:构造示例数据(可跳过,直接套用后续逻辑到你的数据)
import pandas as pd # 示例原表:每一行对应1个主体,列后缀数字为任务编号 df1 = pd.DataFrame({ 'user_name': ['john', 'sally', 'tom'], 'start_t_1': ['2024-01-01', '2024-01-02', '2024-01-03'], 'end_t_1': ['2024-01-05', '2024-01-06', '2024-01-07'], 'weight_1': [10, 20, 30], 'start_t_2': ['2024-01-08', '2024-01-09', None], 'end_t_2': ['2024-01-12', '2024-01-13', None], 'weight_2': [15, 25, None], 'start_t_3': [None, '2024-01-15', None], 'end_t_3': [None, '2024-01-18', None], 'weight_3': [None, 35, None] })
步骤2:通用转换代码
# 可选:如果原表没有单独的主体标识列,先执行这行新增临时行号 # df1 = df1.reset_index(names='temp_row_id') df_long = pd.wide_to_long( df1, stubnames=['start_t', 'end_t', 'weight'], # 任务属性列的公共前缀,和你的列名前缀保持一致即可 i='user_name', # 原表中标识单条主体的列,多列传列表即可,用临时行号的话填'temp_row_id' j='task_id', # 转换后存储任务编号的列名,可自定义 sep='_', # 列名前缀和任务编号之间的分隔符 suffix=r'\d+' # 匹配任务编号的正则,默认匹配任意长度数字 ).reset_index() # 过滤空任务行(主体任务数小于k时产生的无效空记录) df_long = df_long.dropna(subset=['start_t', 'end_t', 'weight']).copy() # 生成task_name,可按需自定义规则 df_long['task_name'] = df_long['user_name'] + '_task_' + df_long['task_id'].astype(str) # 如果不需要关联主体,也可以直接生成独立任务名: # df_long['task_name'] = 'task_' + df_long['task_id'].astype(str) # 提取目标字段得到最终结果 df2 = df_long[['task_name', 'start_t', 'end_t', 'weight']].reset_index(drop=True)
效果验证
输出的df2格式如下,每个任务独占一行:
| task_name | start_t | end_t | weight |
|---|---|---|---|
| john_task_1 | 2024-01-01 | 2024-01-05 | 10 |
| john_task_2 | 2024-01-08 | 2024-01-12 | 15 |
| sally_task_1 | 2024-01-02 | 2024-01-06 | 20 |
| sally_task_2 | 2024-01-09 | 2024-01-13 | 25 |
| sally_task_3 | 2024-01-15 | 2024-01-18 | 35 |
| tom_task_1 | 2024-01-03 | 2024-01-07 | 30 |
内容的提问来源于stack exchange,提问作者evgniy tayarov
相关产品推荐
相关产品推荐

