如何在Python中基于行列映射键快速聚合高分辨率数组至粗分辨率数组?
高效聚合高分辨率numpy数组到粗分辨率的方法
针对你遇到的基于行列映射键的数组聚合问题,暴力循环在大数据量下效率极低,这里提供两种矢量化的高效解决方案,完全避免显式循环:
方法一:使用numpy原生函数(无需额外依赖)
核心思路是将二维的行列映射转换为一维的唯一组索引,利用np.bincount同时计算每个组的总和与元素数量,最后得到均值:
import numpy as np # 示例数据 FIN = np.array([[44., 92., 65., 38., 44., 53.], [ 3., 24., 33., 60., 74., 55.], [89., 1., 9., 16., 79., 22.], [55., 69., 37., 97., 55., 89.], [ 4., 35., 81., 81., 2., 20.], [63., 6., 16., 59., 14., 37.]]) ROWS = np.array([[0, 0, 0, 0, 1, 1], [0, 0, 0, 0, 1, 1], [1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1], [2, 2, 2, 2, 2, 2], [2, 2, 2, 2, 2, 2]]) COLS = np.array([[0, 0, 1, 1, 2, 2], [0, 0, 1, 1, 2, 2], [0, 0, 1, 1, 2, 2], [0, 0, 1, 1, 2, 2], [1, 1, 1, 1, 2, 2], [1, 1, 1, 1, 2, 2]]) # 1. 将二维行列映射转换为一维唯一索引 coarse_shape = (3, 3) group_indices = np.ravel_multi_index((ROWS, COLS), coarse_shape) # 2. 用bincount计算每个组的总和与元素数量 sum_vals = np.bincount(group_indices.ravel(), weights=FIN.ravel()) count_vals = np.bincount(group_indices.ravel()) # 3. 计算均值并重塑为粗分辨率形状 COR = (sum_vals / count_vals).reshape(coarse_shape) print(COR)
输出结果:
[[35.75 54. 61.5 ] [37.83333333 37.25 59.8 ] [27.16666667 27.16666667 23. ]]
方法二:使用scipy.ndimage(适合复杂聚合需求)
如果需要扩展到求和、最大值等其他聚合操作,scipy.ndimage模块的对应函数会更简洁:
from scipy import ndimage # 构造唯一标签 group_indices = np.ravel_multi_index((ROWS, COLS), coarse_shape) # 直接计算每个标签对应的均值 COR = ndimage.mean(FIN, labels=group_indices, index=np.arange(coarse_shape[0]*coarse_shape[1])) COR = COR.reshape(coarse_shape) print(COR)
核心优势
- 无显式循环:依托numpy/scipy的底层C实现,效率远超Python层面的嵌套循环
- 通用性强:方法一可扩展到加权平均、求和等操作;方法二支持
ndimage.sum、ndimage.max等多种聚合函数 - 代码简洁:逻辑清晰,无需冗余的循环判断
内容的提问来源于stack exchange,提问作者newbieee
相关产品推荐
相关产品推荐

