You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求基于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 13:18:27