如何用Pandas/Numpy判断行内值是否在指定区间并生成isZone列
高效实现方案
第一步:优化获取各Zone的上下限
你原来的for循环可以用groupby直接聚合,避免逐行循环,效率更高:
# 按Labels分组,每组按level排序后取首尾行(对应min和max的行) grouped = df_labels.groupby('Labels').apply(lambda x: x.sort_values('level').iloc[[0, -1]]) # 提取测量列的上下限,整理为数组格式 # bounds形状为 (Zone数量, 2, 4),对应[每个Zone, min/max, 4个测量列] bounds = grouped.drop(['Labels', 'level'], axis=1).values.reshape(-1, 2, 4) # 拆分出min和max数组,形状均为(Zone数量, 4) filter_mins = bounds[:, 0, :] filter_maxs = bounds[:, 1, :]
第二步:用Numpy向量化判断生成isZone列
利用Numpy的广播特性,实现全量数据的快速判断,无需逐行循环:
import numpy as np # 提取测量数据为Numpy数组,形状为(行数, 4) meas_data = df_meas[['meas1', 'meas2', 'meas3', 'meas4']].values # 广播比较:判断每个测量值是否落在对应Zone的区间内 # 扩展meas_data维度为(行数, 1, 4),与(Zone数量,4)的上下限数组广播,得到(行数, Zone数量,4)的布尔数组 in_zone = (meas_data[:, None, :] >= filter_mins) & (meas_data[:, None, :] <= filter_maxs) # 逐行判断:是否存在任意Zone,该行有至少一个测量值落在该Zone区间内 # 先对每个Zone的4个测量值取any(是否有值在区间),再对所有Zone取any(是否有符合条件的Zone) df_meas['isZone'] = in_zone.any(axis=2).any(axis=1)
关键说明
- 整个过程完全基于Numpy向量化操作,避免了Python层面的循环,处理数千行数据的速度会比Pandas逐行判断快一个数量级以上。
- 广播机制自动完成了行与Zone的全量匹配,无需手动嵌套循环。
- 如果你的需求是判断每个测量值是否落在对应Zone的区间(而非任意Zone),只需调整最后一步的聚合逻辑即可。
内容的提问来源于stack exchange,提问作者lostinpython
相关产品推荐
相关产品推荐

