求基于NumPy的非重叠方形窗口自定义空间约简高效方法
非重叠方形窗口的自定义约简实现方法
针对大型栅格数组的非重叠块自定义约简,推荐以下几种高效方案:
1. 使用skimage的view_as_blocks(最简洁)
skimage.util.view_as_blocks专门用于生成非重叠的块视图,无需复制数据,可直接对块执行自定义约简:
import numpy as np from skimage.util import view_as_blocks # 示例数组 arr = np.array([[4, 7, 2, 0], [4, 9, 4, 2], [2, 8, 8, 8], [6, 3, 5, 8]]) # 生成2x2的非重叠块视图 blocks = view_as_blocks(arr, block_shape=(2, 2)) # 对每个块执行max约简(可替换为任意自定义函数) result = blocks.max(axis=(2, 3)) print(result)
输出:
array([[9, 4], [8, 8]])
该方法支持任意自定义约简函数,只需将max替换为你的函数(比如自定义统计、滤波逻辑),只要函数能处理块的维度即可。
2. 纯numpy实现(无第三方依赖)
通过reshape和transpose重塑数组为块结构,实现非重叠块的约简:
import numpy as np arr = np.array([[4, 7, 2, 0], [4, 9, 4, 2], [2, 8, 8, 8], [6, 3, 5, 8]]) block_size = 2 rows, cols = arr.shape # 计算块的行列数 n_block_rows = rows // block_size n_block_cols = cols // block_size # 重塑并转置,得到(n_block_rows, n_block_cols, block_size, block_size)的块结构 blocks = arr.reshape(n_block_rows, block_size, n_block_cols, block_size).transpose(0, 2, 1, 3) # 执行约简操作 result = blocks.max(axis=(2, 3)) print(result)
此方法完全依赖numpy,适合无法安装skimage的环境,性能与view_as_blocks相当。
3. Numba加速自定义循环(复杂逻辑首选)
如果你的自定义约简逻辑无法通过numpy广播实现,用Numba对循环进行JIT编译,可将慢循环加速至接近numpy内置函数的性能:
import numpy as np from numba import njit @njit def block_reduce(arr, block_size, reduce_func): rows, cols = arr.shape n_block_rows = rows // block_size n_block_cols = cols // block_size result = np.empty((n_block_rows, n_block_cols), dtype=arr.dtype) for i in range(n_block_rows): for j in range(n_block_cols): # 提取当前非重叠块 block = arr[i*block_size:(i+1)*block_size, j*block_size:(j+1)*block_size] result[i, j] = reduce_func(block) return result # 自定义约简函数示例(可替换为任意逻辑) def custom_max(block): return block.max() arr = np.array([[4, 7, 2, 0], [4, 9, 4, 2], [2, 8, 8, 8], [6, 3, 5, 8]]) result = block_reduce(arr, 2, custom_max) print(result)
边界处理说明
若数组行列数无法被块大小整除,可先裁剪数组至可整除的尺寸:
rows, cols = arr.shape arr_cropped = arr[:rows//block_size*block_size, :cols//block_size*block_size]
内容的提问来源于stack exchange,提问作者cefect
相关产品推荐
相关产品推荐

