如何在Pandas中筛选同一系统下重复同时触发的传感器数据行
问题描述
给定如下Pandas DataFrame:
import pandas as pd data= [['A','Sensor1','1/12/2023 2:00:00 AM'],['A','Sensor2','1/12/2023 2:00:00 AM'],['A','Sensor7','1/12/2023 2:00:00 AM'],['A','Sensor3','1/12/2023 2:00:00 AM'],['A','Sensor1', '2/12/2023 12:00:00 PM'],['A','Sensor2','2/12/2023 12:00:00 PM'],['A','Sensor7','2/12/2023 12:00:00 PM'],['A','Sensor4','3/12/2023 3:00:00 AM'],['B','Sensor7','2/12/2023 5:00:00 AM'],['B','Sensor8','2/12/2023 5:00:00 AM'],['B','Sensor2','2/12/2023 5:00:00 AM'],['B','Sensor5','4/12/2023 4:00:00 AM'],['B','Sensor7','6/12/2023 5:00:00 AM'],['B','Sensor8','6/12/2023 5:00:00 AM'],['B','Sensor3','6/12/2023 5:00:00 AM'],['C','Sensor1','6/12/2023 5:00:00 AM'],['C','Sensor2','7/12/2023 5:00:00 AM']] df = pd.DataFrame(data,columns =['System','Sensor','SensorTime'])
需要筛选出满足以下条件的数据行:同一System中,同一月份内,某组Sensor在至少两个不同的SensorTime点都同时触发。比如:
- System A的Sensor1、Sensor2、Sensor7在12月的两个不同时间点都同时触发
- System B的Sensor7、Sensor8在12月的两个不同时间点都同时触发
期望输出如下:
| System | Sensor | SensorTime |
|---|---|---|
| A | Sensor1 | 1/12/2023 2:00:00 AM |
| A | Sensor2 | 1/12/2023 2:00:00 AM |
| A | Sensor7 | 1/12/2023 2:00:00 AM |
| A | Sensor1 | 2/12/2023 12:00:00 PM |
| A | Sensor2 | 2/12/2023 12:00:00 PM |
| A | Sensor7 | 2/12/2023 12:00:00 PM |
| B | Sensor7 | 2/12/2023 5:00:00 AM |
| B | Sensor8 | 2/12/2023 5:00:00 AM |
| B | Sensor7 | 6/12/2023 5:00:00 AM |
| B | Sensor8 | 6/12/2023 5:00:00 AM |
目前通过iterrows遍历每个System分组,将Sensor和SensorTime存入列表后比较筛选,请问有没有更高效的实现方式?
高效实现方案
完全可以用Pandas的分组、聚合、匹配等向量式操作替代循环遍历,避免iterrows带来的性能损耗,步骤如下:
步骤1:解析时间,提取月份信息
先把SensorTime转为datetime类型,并提取年份-月份作为分组依据,确保只在同一月份内做比较:
df['SensorTime'] = pd.to_datetime(df['SensorTime']) df['year_month'] = df['SensorTime'].dt.to_period('M')
步骤2:按System+年月+时间点分组,生成Sensor组标识
每个时间点触发的Sensor集合是判断重复组的核心,我们将每个时间点的Sensor排序后拼接成字符串(或用frozenset),保证Sensor顺序不影响组的判断:
# 按System、年月、时间点分组,聚合得到该时间点的Sensor组字符串 grouped_time = df.groupby(['System', 'year_month', 'SensorTime'])['Sensor'].agg( lambda x: ','.join(sorted(x)) ).reset_index(name='sensor_group')
步骤3:筛选重复出现的Sensor组
在同一System+年月下,若某个Sensor组出现多次,说明这些Sensor在多个时间点同时触发:
# 统计每个Sensor组在对应System+年月下的出现次数 group_counts = grouped_time.groupby(['System', 'year_month', 'sensor_group']).size().reset_index(name='count') # 保留出现次数≥2的有效组 valid_groups = group_counts[group_counts['count'] >= 2][['System', 'year_month', 'sensor_group']]
步骤4:匹配回原始数据,得到最终结果
将有效Sensor组关联回时间点分组数据,再匹配到原始DataFrame:
# 关联有效组和时间点数据,得到对应的触发时间点 valid_time_points = pd.merge(grouped_time, valid_groups, on=['System', 'year_month', 'sensor_group']) # 关联回原始DataFrame,筛选出目标行 result = pd.merge(df, valid_time_points[['System', 'SensorTime']], on=['System', 'SensorTime']) # 按System、时间、Sensor排序,与期望输出一致 result = result.sort_values(['System', 'SensorTime', 'Sensor']).reset_index(drop=True) # 可选:移除临时的year_month列 result = result.drop('year_month', axis=1)
执行后result就是符合要求的输出,这种方式完全利用Pandas的内置优化,比iterrows循环高效得多,数据量越大优势越明显。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

