如何基于同traceId内的service+operation顺序去重并求duration均值?
解决方案
要实现移除同一traceId内service+operation顺序重复的行(实际是指不同traceId之间的service+operation序列完全重复)并计算对应duration均值的需求,可以按以下步骤实现:
import pandas as pd # 初始DataFrame start_df = pd.DataFrame({'traceId':['a','a','a','a','b','b','b','b', 'c','c','c','c'], 'service':['cartservice', 'frontend-proxy', 'frontend-proxy', 'frontend', 'cartservice', 'frontend-proxy', 'frontend-proxy', 'frontend', 'a','a','b','c'], 'operation': ['router frontend egress', 'ingress', 'oteldemo.CartService/GetCart', 'GET', 'router frontend egress', 'ingress', 'oteldemo.CartService/GetCart', 'GET', 'a-1', 'a-1', 'b-1', 'c-1'], 'duration': [1,2,3,4, 2,3,4,5, 5,5,5,5]}) # 1. 为每个traceId生成唯一的序列标识(service+operation的顺序组合) def generate_sequence(group): return tuple(zip(group['service'], group['operation'])) trace_sequences = start_df.groupby('traceId').apply(generate_sequence) # 2. 筛选出重复出现的序列(即有多个traceId共享同一序列) duplicate_seqs = trace_sequences[trace_sequences.duplicated(keep=False)].unique() # 3. 为每行添加组内位置标记(用于对齐重复序列的对应行) start_df['seq_pos'] = start_df.groupby('traceId').cumcount() start_df['sequence'] = start_df['traceId'].map(trace_sequences) # 4. 处理重复序列:分组计算对应位置的duration均值,保留第一个出现的traceId duplicate_processed = start_df[start_df['sequence'].isin(duplicate_seqs)].groupby(['sequence', 'seq_pos'], as_index=False).agg( traceId=('traceId', 'first'), service=('service', 'first'), operation=('operation', 'first'), duration=('duration', 'mean') ).drop(columns=['sequence', 'seq_pos']) # 5. 处理唯一序列:直接保留原行(无重复序列,均值为自身) unique_processed = start_df[~start_df['sequence'].isin(duplicate_seqs)].drop(columns=['sequence', 'seq_pos']) # 6. 合并结果并排序 result_df = pd.concat([duplicate_processed, unique_processed]).sort_values('traceId').reset_index(drop=True) print(result_df)
运行后输出的result_df将与你提供的示例完全一致。
原代码问题分析
你之前的代码逻辑存在核心错误:
- 定义的
has_same_order函数是判断单个traceId组内所有行的service和operation都与第一行相同,这和需求中"不同traceId之间的service+operation序列重复"的逻辑完全不符。 - 后续的
filter步骤会错误地过滤掉所有组内行不统一的traceId,导致结果完全偏离预期。
内容的提问来源于stack exchange,提问作者eskoddda
相关产品推荐
相关产品推荐

