14万行DataFrame行赋值优化:基于列值阈值比较的提速方案
高效优化方案
1. 快速生成类别列
放弃逐行判断的低效方式,用numpy向量化操作直接生成类别,速度比apply快几个数量级:
import numpy as np # 生成类别列:temp>2→0,temp<-2→1,其余→2 ts['temp_idx'] = np.where(ts['temp'] > 2, 0, np.where(ts['temp'] < -2, 1, 2))
2. 预处理湿度参考数组
如果你的h_ref数组未排序,先对每个参考数组做排序+原索引映射(已排序可跳过此步),为后续二分查找做准备:
# 预处理每个h_ref数组,保存排序后的值和对应的原索引 sorted_h_ref = [] for arr in h_ref: sort_idx = np.argsort(arr) sorted_h_ref.append((arr[sort_idx], sort_idx))
3. 向量化查找最接近湿度的索引
用numpy的searchsorted做二分查找,替代逐行计算差值的笨方法,这是性能提升的核心:
def get_closest_h_idx(h_values, sorted_vals, sorted_indices): # 二分查找找到插入位置 insert_pos = np.searchsorted(sorted_vals, h_values, side="left") # 处理边界,避免索引越界 insert_pos = np.clip(insert_pos, 1, len(sorted_vals)-1) # 比较插入位置前后的元素,确定哪个离当前h值更近 left_diff = h_values - sorted_vals[insert_pos-1] right_diff = sorted_vals[insert_pos] - h_values # 映射回原数组的索引 final_sort_idx = np.where(left_diff <= right_diff, insert_pos-1, insert_pos) return sorted_indices[final_sort_idx] # 按类别分组处理 mask_0 = ts['temp_idx'] == 0 mask_1 = ts['temp_idx'] == 1 mask_2 = ts['temp_idx'] == 2 ts.loc[mask_0, 'h_idx'] = get_closest_h_idx(ts.loc[mask_0, 'h'].values, *sorted_h_ref[0]) ts.loc[mask_1, 'h_idx'] = get_closest_h_idx(ts.loc[mask_1, 'h'].values, *sorted_h_ref[1]) ts.loc[mask_2, 'h_idx'] = get_closest_h_idx(ts.loc[mask_2, 'h'].values, *sorted_h_ref[2])
原方案低效的原因
apply(axis=1)本质是Python级别的逐行循环,14万行的循环开销极大;np.vectorize只是语法糖,底层还是循环,且如果h_ref数组较大,广播生成的差值数组会直接撑爆内存。
这种向量化方案全程用numpy/pandas的C级操作,无Python循环,处理14万行数据的时间可压缩到几秒内。
内容的提问来源于stack exchange,提问作者user13132640
相关产品推荐
相关产品推荐

