温度DataFrame处理:如何减少重复的≥50条件检查次数?
优化重复条件检查的Pandas代码方案
问题背景
我有一个温度数据的DataFrame,结构如下:
| datetime | 0 | 1 | 2 | 3 |
|---|---|---|---|---|
| 21-10-2022 09:17:21.1721 | 0 | 47.79 | 43.62 | 46.22 |
| 21-10-2022 09:17:31.1731 | 0 | 47.79 | 43.56 | 46.22 |
| 21-10-2022 09:17:41.1741 | 0 | 47.82 | 43.59 | 46.32 |
| 21-10-2022 09:17:51.1751 | 0 | 47.85 | 43.62 | 46.32 |
| 21-10-2022 09:18:01.181 | 0 | 47.85 | 43.65 | 46.45 |
| 21-10-2022 09:18:11.1811 | 0 | 47.85 | 43.56 | 56.42 |
| 21-10-2022 09:18:21.1821 | 0 | 57.85 | 43.59 | 46.52 |
需求
- 根据现有列的值创建新列
- 使用
append生成后续可用的列表
期望输出的DataFrame:
| datetime | 0 | 1 | 2 | 3 | temp_ng | 900 | 901 | 902 | 903 |
|---|---|---|---|---|---|---|---|---|---|
| 21-10-2022 09:17:21.1721 | 0 | 47.79 | 43.62 | 46.22 | 0 | 0 | 0 | 0 | 0 |
| 21-10-2022 09:17:31.1731 | 0 | 47.79 | 43.56 | 46.22 | 0 | 0 | 0 | 0 | 0 |
| 21-10-2022 09:17:41.1741 | 0 | 47.82 | 43.59 | 46.32 | 0 | 0 | 0 | 0 | 0 |
| 21-10-2022 09:17:51.1751 | 0 | 47.85 | 43.62 | 46.32 | 0 | 0 | 0 | 0 | 0 |
| 21-10-2022 09:18:01.181 | 0 | 47.85 | 43.65 | 46.45 | 0 | 0 | 0 | 0 | 0 |
| 21-10-2022 09:18:11.1811 | 0 | 47.85 | 43.56 | 56.42 | 1 | 0 | 0 | 0 | 1 |
| 21-10-2022 09:18:21.1821 | 0 | 57.85 | 43.59 | 46.52 | 1 | 0 | 1 | 0 | 0 |
期望生成的列表:
issue = ['1 is not_ok', '3 is not_ok']
当前可运行代码
issue = [] # creates a new list for col in range(0, 4): df.loc[df[col] >= 50, 'temp_ng'] = 1 # 1.chk all rows & create new 'temp_ng' column with 1/0 df.loc[df[col] >= 50, 900 + col] = 1 # 2.again chk all rows &new columns eg 900,901,902,903 if (df[col] >= 50).any(): # 3.again chk all rows & to create a list issue.append(str(col) +' is not_ok')
疑问
我需要对每列的所有行重复三次检查df[col]≥50的条件(通过.loc和if语句)。由于检查条件相同,是否有办法减少重复检查的次数?
优化方案
可以通过复用布尔掩码或者向量化操作减少重复计算,以下是两种可行方案:
方案1:复用布尔掩码(保留循环)
每个列只计算一次df[col] >= 50的结果,后续所有操作都基于这个掩码完成:
# 先初始化所有新列,默认值设为0,避免出现NaN df['temp_ng'] = 0 for col in range(0, 4): df[900 + col] = 0 issue = [] for col in range(0, 4): # 仅计算一次条件掩码 mask = df[col] >= 50 # 复用掩码更新temp_ng列 df.loc[mask, 'temp_ng'] = 1 # 复用掩码更新对应90x列 df.loc[mask, 900 + col] = 1 # 复用掩码的any()结果判断是否添加到issue列表 if mask.any(): issue.append(f"{col} is not_ok")
方案2:向量化操作(无循环,效率更高)
利用Pandas的矩阵运算一次性处理所有列,彻底避免循环和重复计算:
# 生成所有目标列的布尔矩阵(每行每列是否满足>=50) mask_matrix = df[[0, 1, 2, 3]] >= 50 # 更新temp_ng列:只要当前行任意一列满足条件就设为1 df['temp_ng'] = mask_matrix.any(axis=1).astype(int) # 生成900-903列:直接将布尔值转为整数(True→1,False→0) df[['900', '901', '902', '903']] = mask_matrix.astype(int) # 生成issue列表:筛选出至少有一行满足条件的列 issue = [f"{col} is not_ok" for col in mask_matrix.columns if mask_matrix[col].any()]
优化说明
- 掩码复用:方案1中每个列仅计算一次条件,后续赋值和判断都直接复用结果,避免了三次重复计算,逻辑更清晰,计算量减少2/3。
- 向量化操作:方案2利用Pandas的批量处理能力,完全摆脱循环,在数据量较大时性能提升显著,代码更简洁。
- 提前初始化列:先将新列设为默认值0,再更新符合条件的行,确保所有行都有值,不会出现缺失值。
内容的提问来源于stack exchange,提问作者user_v27
相关产品推荐
相关产品推荐

