基于Pandas Groupby处理路由器CSV:求各QIN的uIN/uOUT最大值及对应时间
嘿,我完全懂你卡在哪了——用groupby的时候,直接取最大值很容易,但要同时把对应的时间戳捞出来就有点绕,毕竟默认的聚合操作会丢失关联的行信息。让我一步步帮你解决这个问题,先从模拟你的数据场景开始:
先明确场景(模拟你的数据样例)
假设你的CSV数据长这样:
QIN,Time,uIN,uOUT RouterA,2024-05-20 08:00,45,60 RouterA,2024-05-20 09:00,70,55 RouterB,2024-05-20 08:30,30,80 RouterB,2024-05-20 10:00,50,90 RouterA,2024-05-20 10:30,65,75
你之前的尝试大概是直接对uIN和uOUT做max()聚合,结果只得到了数值,丢了对应的时间,对吧?
解法1:用groupby.apply()自定义逻辑(直观易懂)
这个方法适合中小数据集,逻辑清晰,能直接拿到你要的所有信息:
import pandas as pd # 读取数据并转换时间格式(这步很重要,不然时间会被当成字符串处理) df = pd.read_csv('router_utilization.csv') df['Time'] = pd.to_datetime(df['Time']) # 定义每个分组的处理函数:找到uIN和uOUT最大值对应的行,提取关键信息 def extract_max_with_time(group): # 找到uIN最大值的行(如果有多个相同最大值,取第一个出现的) uIN_max_row = group.loc[group['uIN'].idxmax()] # 找到uOUT最大值的行 uOUT_max_row = group.loc[group['uOUT'].idxmax()] # 整理成需要的格式返回 return pd.Series({ 'uIN_Max': uIN_max_row['uIN'], 'uIN_Max_Time': uIN_max_row['Time'], 'uOUT_Max': uOUT_max_row['uOUT'], 'uOUT_Max_Time': uOUT_max_row['Time'] }) # 按QIN分组,应用自定义函数 final_result = df.groupby('QIN').apply(extract_max_with_time).reset_index() print(final_result)
得到的期望结果:
QIN uIN_Max uIN_Max_Time uOUT_Max uOUT_Max_Time 0 RouterA 70 2024-05-20 09:00:00 75 2024-05-20 10:30:00 1 RouterB 50 2024-05-20 10:00:00 90 2024-05-20 10:00:00
解法2:用transform+布尔索引(大数据集更高效)
如果你的每日数据量很大,上面的apply()可能有点慢,试试这个方法,效率更高:
import pandas as pd df = pd.read_csv('router_utilization.csv') df['Time'] = pd.to_datetime(df['Time']) # 计算每个QIN组内的uIN、uOUT最大值,广播到每行 df['uIN_Group_Max'] = df.groupby('QIN')['uIN'].transform('max') df['uOUT_Group_Max'] = df.groupby('QIN')['uOUT'].transform('max') # 分别筛选出uIN和uOUT达到组内最大值的行,去重后合并 uIN_max_records = df[df['uIN'] == df['uIN_Group_Max']][['QIN', 'uIN', 'Time']].rename( columns={'uIN':'uIN_Max', 'Time':'uIN_Max_Time'} ).drop_duplicates('QIN') # 避免同一QIN有多个相同最大值的情况 uOUT_max_records = df[df['uOUT'] == df['uOUT_Group_Max']][['QIN', 'uOUT', 'Time']].rename( columns={'uOUT':'uOUT_Max', 'Time':'uOUT_Max_Time'} ).drop_duplicates('QIN') # 合并两个结果 final_result = pd.merge(uIN_max_records, uOUT_max_records, on='QIN') print(final_result)
一些关键注意事项
- 必须把
Time列转为datetime类型,不然字符串排序或索引会出错; - 如果同一个QIN的
uIN有多个相同最大值,idxmax()会取第一个出现的,要是想取最后一个,可以先对分组按时间排序再用iloc[-1]; - 如果是处理每日数据,可以先加一步日期过滤:
df = df[df['Time'].dt.date == pd.to_datetime('2024-05-20').date()],确保只处理当天的数据。
内容的提问来源于stack exchange,提问作者RMax
相关产品推荐
相关产品推荐

