如何基于系统名称与序列条件偏移Pandas行,关联上一序列数据?
解决方案:关联Pandas DataFrame中同系统的上一序列数据
你的需求是按系统名称分组,匹配同系统下序列为当前序列-1的状态和时间,以下是两种可行的实现方法,同时会说明你原代码的问题。
方法一:使用groupby + shift(推荐)
因为序列是按系统自增的,先按系统名称分组,确保每组内按序列排序后,用shift(1)即可获取上一条记录的对应字段:
import pandas as pd # 构造示例数据 data = { 'id': ['001', '002', '003', '004', '005', '006', '007', '008'], '时间': ['2022-06-01 10:00:12', '2022-06-01 10:01:02', '2022-06-01 10:01:45', '2022-06-01 10:01:52', '2022-06-01 10:02:00', '2022-06-01 10:02:02', '2022-06-01 10:02:13', '2022-06-01 10:01:02'], '系统名称': ['A', 'B', 'A', 'B', 'C', 'B', 'A', 'C'], '状态': ['RUNNING', 'RUNNING', 'DONE', 'DONE', 'RUNNING', 'ERROR', 'IDLE', 'DONE'], '序列': [1, 1, 2, 2, 1, 3, 3, 2] } df = pd.DataFrame(data) # 按系统分组,组内按序列排序,再获取上一状态和时间 df_sorted = df.sort_values(['系统名称', '序列']) df_sorted['上一状态'] = df_sorted.groupby('系统名称')['状态'].shift(1) df_sorted['上一时间'] = df_sorted.groupby('系统名称')['时间'].shift(1) # 还原原id顺序并处理空值 result = df_sorted.set_index('id').reindex(df['id']).reset_index() result['上一状态'] = result['上一状态'].fillna(pd.NA) result['上一时间'] = result['上一时间'].fillna('nta') # 输出目标格式 print(result[['id', '时间', '系统名称', '状态', '序列', '上一状态', '上一时间']])
方法二:使用merge关联自身
通过将DataFrame与自身合并,匹配同系统下序列 = 当前序列-1的记录:
import pandas as pd # 构造示例数据 data = { 'id': ['001', '002', '003', '004', '005', '006', '007', '008'], '时间': ['2022-06-01 10:00:12', '2022-06-01 10:01:02', '2022-06-01 10:01:45', '2022-06-01 10:01:52', '2022-06-01 10:02:00', '2022-06-01 10:02:02', '2022-06-01 10:02:13', '2022-06-01 10:01:02'], '系统名称': ['A', 'B', 'A', 'B', 'C', 'B', 'A', 'C'], '状态': ['RUNNING', 'RUNNING', 'DONE', 'DONE', 'RUNNING', 'ERROR', 'IDLE', 'DONE'], '序列': [1, 1, 2, 2, 1, 3, 3, 2] } df = pd.DataFrame(data) # 准备合并用的辅助表,重命名字段 prev_df = df.rename(columns={'状态': '上一状态', '时间': '上一时间', '序列': '上一序列'}) # 匹配规则:同系统,当前序列 = 上一序列 + 1 result = pd.merge(df, prev_df, left_on=['系统名称', '序列'], right_on=['系统名称', '上一序列'], how='left') # 整理列名并处理空值 result = result[['id_x', '时间_x', '系统名称', '状态_x', '序列_x', '上一状态', '上一时间']] result.columns = ['id', '时间', '系统名称', '状态', '序列', '上一状态', '上一时间'] result['上一状态'] = result['上一状态'].fillna(pd.NA) result['上一时间'] = result['上一时间'].fillna('nta') print(result)
原代码的问题说明
- 语法错误:
df['system_name']=df['system_name']是赋值操作,不是比较,应改为==; - 逻辑缺陷:没有按
系统名称分组,df['sequence'].values-1会跨系统匹配序列,导致关联逻辑混乱,无法精准匹配同系统的上一序列数据。
内容的提问来源于stack exchange,提问作者YVS1997
相关产品推荐
相关产品推荐

