切片矩阵后,如何对相邻子块的边界值求平均?
子矩阵边界与相邻子矩阵对应边界求平均的实现方法
问题背景
现有256×256矩阵A,已划分为16个32×32的非重叠子矩阵,需将每个子矩阵的边界值与相邻子矩阵的对应边界值求平均。以下以12×12矩阵划分为16个3×3子矩阵的示例,给出具体实现步骤。
前置准备:定义分块与合并函数
首先实现矩阵分块和合并的辅助函数,用于拆分原矩阵为子块,处理后再合并回原尺寸:
import numpy as np def blockshaped(arr, nrows, ncols): """将数组划分为(nrows×ncols)的非重叠子块""" h, w = arr.shape return (arr.reshape(h//nrows, nrows, -1, ncols) .swapaxes(1, 2) .reshape(-1, nrows, ncols)) def unblockshaped(arr, h, w): """将子块数组合并为h×w的原矩阵""" n, nrows, ncols = arr.shape return (arr.reshape(h//nrows, -1, nrows, ncols) .swapaxes(1, 2) .reshape(h, w))
示例实现(12×12矩阵)
1. 生成矩阵并分块
# 生成12×12的示例矩阵 c = np.arange(144).reshape((12, 12)) block_size = 3 # 拆分为3×3的子块 blocks = blockshaped(c, block_size, block_size) # 将一维子块数组重塑为4×4的子块网格(对应原矩阵的行列划分) block_grid = blocks.reshape(4, 4, block_size, block_size)
2. 遍历子块处理边界平均
# 遍历每个子块的网格位置(i,j) for i in range(4): for j in range(4): current = block_grid[i, j] # 处理上边界:与上方子块的下边界求平均(非第一行子块) if i > 0: upper = block_grid[i-1, j] current[0, :] = (current[0, :] + upper[-1, :]) / 2 upper[-1, :] = current[0, :] # 同步更新上方子块的对应边界 # 处理下边界:与下方子块的上边界求平均(非最后一行子块) if i < 3: lower = block_grid[i+1, j] current[-1, :] = (current[-1, :] + lower[0, :]) / 2 lower[0, :] = current[-1, :] # 处理左边界:与左方子块的右边界求平均(非第一列子块) if j > 0: left = block_grid[i, j-1] current[:, 0] = (current[:, 0] + left[:, -1]) / 2 left[:, -1] = current[:, 0] # 处理右边界:与右方子块的左边界求平均(非最后一列子块) if j < 3: right = block_grid[i, j+1] current[:, -1] = (current[:, -1] + right[:, 0]) / 2 right[:, 0] = current[:, -1]
3. 合并处理后的子块
# 将处理后的子块网格合并回12×12矩阵 processed_matrix = unblockshaped(block_grid.reshape(-1, block_size, block_size), 12, 12)
适配256×256矩阵的修改
只需调整分块大小和网格维度即可:
# 假设A是256×256的输入矩阵 block_size = 32 blocks = blockshaped(A, block_size, block_size) # 256/32=8,所以子块网格是8×8 block_grid = blocks.reshape(8, 8, block_size, block_size) # 遍历处理逻辑不变,仅循环范围改为range(8) for i in range(8): for j in range(8): current = block_grid[i, j] # 以下边界处理逻辑与示例完全一致 if i > 0: upper = block_grid[i-1, j] current[0, :] = (current[0, :] + upper[-1, :]) / 2 upper[-1, :] = current[0, :] if i < 7: lower = block_grid[i+1, j] current[-1, :] = (current[-1, :] + lower[0, :]) / 2 lower[0, :] = current[-1, :] if j > 0: left = block_grid[i, j-1] current[:, 0] = (current[:, 0] + left[:, -1]) / 2 left[:, -1] = current[:, 0] if j < 7: right = block_grid[i, j+1] current[:, -1] = (current[:, -1] + right[:, 0]) / 2 right[:, 0] = current[:, -1]
关键逻辑说明
- 将子块数组重塑为二维网格,便于通过行列索引快速定位相邻子块
- 处理边界时同步更新相邻子块的对应边界,避免重复计算同一共享边界
- 边缘子块(如第一行、最后一列)仅处理存在的相邻边界
内容的提问来源于stack exchange,提问作者Carlos
相关产品推荐
相关产品推荐

