3D Numpy数组带边界处理的加权移动平均实现问询
3D Numpy数组的加权移动平均(含边缘权重归一化)
核心思路
利用scipy.ndimage.convolve实现高效卷积操作,通过两次卷积分别计算:
- 分子:原数组与权重核的卷积,得到每个位置的加权和
- 分母:全1数组与权重核的卷积,得到每个位置的有效权重总和(用于归一化)
最后将分子除以分母,自动完成边缘/角落的有效邻域加权平均计算,完全避免手动循环造轮子。
完整实现代码
import numpy as np from scipy.ndimage import convolve # 生成测试数据 np.random.seed(1) A = np.random.uniform(size=(10, 10, 10)) # 定义自定义3D权重核 Weights_of_3D_Kernel = np.array([[ [0.1, 0.1, 0.1, 0.1, 0.1], [0.1, 0.3, 0.5, 0.3, 0.1], [0.1, 0.5, 0.7, 0.5, 0.1], [0.1, 0.3, 0.5, 0.3, 0.1], [0.1, 0.1, 0.1, 0.1, 0.1]], [[0.1, 0.1, 0.1, 0.1, 0.1], [0.1, 0.5, 0.7, 0.5, 0.1], [0.1, 0.7, 1, 0.7, 0.1], # 源点权重为1 [0.1, 0.5, 0.7, 0.5, 0.1], [0.1, 0.1, 0.1, 0.1, 0.1]], [[0.1, 0.1, 0.1, 0.1, 0.1], [0.1, 0.3, 0.5, 0.3, 0.1], [0.1, 0.5, 0.7, 0.5, 0.1], [0.1, 0.3, 0.5, 0.3, 0.1], [0.1, 0.1, 0.1, 0.1, 0.1]] ]) # 计算加权和(分子):边界外填充0,自动忽略超出数组的核部分 weighted_sum = convolve(A, Weights_of_3D_Kernel, mode='constant') # 计算有效权重总和(分母) weight_total = convolve(np.ones_like(A), Weights_of_3D_Kernel, mode='constant') # 得到最终加权平均结果 weighted_average = weighted_sum / weight_total
关键细节说明
- 边缘处理:
mode='constant'会在数组边界外填充0,卷积时这些区域的权重不会被计入总和,因此weight_total自动得到当前点实际可用的邻域权重之和,而非核的总权重,完美适配边缘/角落的计算需求。 - 效率优势:
scipy.ndimage.convolve基于底层优化实现,比手动遍历每个点快数个数量级,完全符合Pythonic"复用现有工具"的原则。 - 核对齐:权重核的中心(权重为1的位置)会自动与当前计算的点对齐,无需手动调整窗口位置。
内容的提问来源于stack exchange,提问作者2023_resolution
相关产品推荐
相关产品推荐

