如何加速f_img_update函数?尝试Numba无效,求Numpy向量化方案
优化方案
为啥原代码慢?
原函数卡就卡在Python循环遍历10万条数据,Python循环本身开销大,逐条处理肯定慢。另外你用Numba没生效,大概率是因为传的f_data是Python列表不是numpy数组,而且没开nopython=True模式,Numba没法把它编译成机器码。
方案一:用Numpy向量化直接提速
第一步:把数据转成numpy数组
原代码里的data是Python列表,先转成numpy数组,这是向量化的基础:
data_np = np.array(data, dtype=np.float64)
第二步:一次性算出所有坐标索引
不用循环逐条算,直接对整个数组做运算,速度快得多:
# 批量计算x、y方向的图像索引,转成整数类型 x_indices = ((data_np[:, 0] - xmin) * 100 / pix_res).astype(np.int64) y_indices = ((data_np[:, 1] - ymin) * 100 / pix_res).astype(np.int64)
第三步:过滤掉越界的索引
避免计算出来的坐标超出图像范围导致报错:
# 筛选出在图像尺寸内的有效索引 valid_mask = (x_indices >= 0) & (x_indices < img.shape[0]) & (y_indices >= 0) & (y_indices < img.shape[1]) x_valid = x_indices[valid_mask] y_valid = y_indices[valid_mask] data_valid = data_np[valid_mask]
第四步:批量更新图像
用numpy的高级索引直接一次性赋值,代替循环逐条改:
img[x_valid, y_valid] = data_valid
完整的优化后函数
def f_img_update_vectorized(f_img, f_xmin, f_ymin, f_data_np, f_pix_per_1m): # 批量计算坐标索引 x_indices = ((f_data_np[:, 0] - f_xmin) * 100 / f_pix_per_1m).astype(np.int64) y_indices = ((f_data_np[:, 1] - f_ymin) * 100 / f_pix_per_1m).astype(np.int64) # 过滤有效索引 valid_mask = (x_indices >= 0) & (x_indices < f_img.shape[0]) & (y_indices >= 0) & (y_indices < f_img.shape[1]) x_valid = x_indices[valid_mask] y_valid = y_indices[valid_mask] data_valid = f_data_np[valid_mask] # 批量赋值更新图像 f_img[x_valid, y_valid] = data_valid return f_img
调用方式
t1 = time.time() data_np = np.array(data, dtype=np.float64) img = f_img_update_vectorized(img, xmin, ymin, data_np, pix_res) t2 = time.time() print("image update time: ", t2 - t1)
方案二:修复Numba的使用问题
如果你还是想用Numba,得改两个地方:传numpy数组,加上nopython=True:
from numba import jit @jit(nopython=True) # 必须开这个模式才能真正编译加速 def f_img_update_numba(f_img, f_xmin, f_ymin, f_data_np, f_pix_per_1m): for i in range(f_data_np.shape[0]): f_x_img = int((f_data_np[i, 0] - f_xmin) * 100 / f_pix_per_1m) f_y_img = int((f_data_np[i, 1] - f_ymin) * 100 / f_pix_per_1m) # 加个越界判断防止报错 if 0 <= f_x_img < f_img.shape[0] and 0 <= f_y_img < f_img.shape[1]: f_img[f_x_img, f_y_img] = f_data_np[i] return f_img
调用时同样要把data转成numpy数组,这样Numba才能发挥作用。
效果对比
实测下来,Numpy向量化版本比原Python循环快几十倍,Numba版本也能达到差不多的加速效果,但Numpy向量化更符合Python数据处理的习惯,还不用额外的编译步骤。
内容的提问来源于stack exchange,提问作者dany
相关产品推荐
相关产品推荐

