按组件名称分组计算连续位置时间差及多维度平均耗时
嘿,我懂你为啥用spread转宽表没搞定了——这个思路其实把问题复杂化了,咱们换个更直接的方式,用分组和窗口函数就能轻松解决你的三个需求。先假设你的DataFrame大概有这些字段:component_name(组件名)、location(位置)、timestamp(时间戳)、component_type(组件类型),下面一步步来实现:
1. 计算每个组件连续位置间的时间差
首先得确保时间戳是 datetime 类型,然后按组件分组并按时间排序,用shift()拿到前一个位置,diff()算出时间差:
import pandas as pd # 先转换时间格式(如果还没转的话) df['timestamp'] = pd.to_datetime(df['timestamp']) # 按组件分组,按时间排序后计算连续位置的时间差 df_sorted = df.sort_values(['component_name', 'timestamp']) df_sorted['prev_location'] = df_sorted.groupby('component_name')['location'].shift(1) df_sorted['time_diff'] = df_sorted.groupby('component_name')['timestamp'].diff()
这样处理后,每一行都会显示当前组件的上一个位置,以及从上一个位置到当前位置的时间差。过滤掉time_diff为NaN的行(也就是组件的第一个位置记录),就是你要的连续位置时间差数据。
2. 统计任意组件在单个位置的平均耗时
这里的“耗时”我默认是指组件从该位置出发到下一个位置的平均时间(如果是停留时间的话,后面我会补充另一种场景)。基于上面的df_sorted,我们按位置分组求平均即可:
# 过滤掉无时间差的行 valid_time_diff = df_sorted.dropna(subset=['time_diff', 'prev_location']) # 单个位置的平均耗时(这里用prev_location代表组件离开的位置) location_avg_time = valid_time_diff.groupby('prev_location')['time_diff'].mean().reset_index() location_avg_time.columns = ['location', 'average_time']
3. 按位置+组件类型维度统计平均耗时
只需要在分组的时候加上component_type就行:
# 按位置+组件类型分组计算平均耗时 location_type_avg_time = valid_time_diff.groupby(['prev_location', 'component_type'])['time_diff'].mean().reset_index() location_type_avg_time.columns = ['location', 'component_type', 'average_time']
补充:如果是统计组件在位置的停留时间
如果你的数据是记录组件进入/离开位置的事件(比如有event_type字段,值为enter/exit),那计算停留时间的方式会稍有不同:
# 按组件+位置分组,取最大时间(离开)减最小时间(进入)得到停留时间 stay_time_df = df.groupby(['component_name', 'location'])['timestamp'].apply(lambda x: x.max() - x.min()).reset_index() stay_time_df.columns = ['component_name', 'location', 'stay_time'] # 单个位置的平均停留时间 location_avg_stay = stay_time_df.groupby('location')['stay_time'].mean().reset_index() # 按位置+组件类型的平均停留时间(先关联组件类型) stay_time_with_type = stay_time_df.merge(df[['component_name', 'component_type']].drop_duplicates(), on='component_name') location_type_avg_stay = stay_time_with_type.groupby(['location', 'component_type'])['stay_time'].mean().reset_index()
为啥之前用spread没成功?因为转宽表后,每个组件的位置列数量可能不一致,而且连续位置的顺序关系会被打乱,处理起来反而更繁琐。用分组+shift/diff的方式,能直接保留组件的时间序列关系,效率也更高。
内容的提问来源于stack exchange,提问作者mjoy
相关产品推荐
相关产品推荐

