
本文介绍如何使用 scipy 和 numpy 实现两个二维数组在指定重叠宽度下的无缝拼接,通过块对角构造与掩码加权平均,避免全矩阵显式分配,天然支持稀疏结构扩展。
本文介绍如何使用 scipy 和 numpy 实现两个二维数组在指定重叠宽度下的无缝拼接,通过块对角构造与掩码加权平均,避免全矩阵显式分配,天然支持稀疏结构扩展。
在科学计算与图像/信号处理中,常需将多个局部矩阵(如分块求解结果、滑动窗口输出或区域拼接)沿某维度“软连接”——即允许指定宽度的重叠,并对重叠区域取平均值以实现平滑过渡。这不同于 scipy.linalg.block_diag 的零填充对角拼接,而是一种带权重的重叠融合(overlap stitching)。本文提供一种简洁、可扩展、内存友好的实现方案,核心思想是:利用块对角矩阵的线性叠加与计数掩码,实现逐元素加权平均。
基本原理
设两个形状均为 (n, n) 的方阵 A 和 B,要求重叠宽度为 overlap(此处指重叠行/列数,本例中为 2)。目标输出矩阵尺寸为 (n + n - overlap, n + n - overlap)。关键洞察在于:
- 将 A 左上对齐放置,B 右下对齐放置,二者在中间 (overlap, overlap) 区域自然重叠;
- 构造两个“位置掩码”矩阵:一个标记 A 的有效区域(其余为 0),另一个标记 B 的有效区域;
- 对应位置相加得到分子(值之和),掩码相加得到分母(覆盖次数),再逐元素除法即得平均值。
该方法完全基于线性代数运算,不涉及循环或索引切片,天然兼容 scipy.sparse 矩阵(只需将 np.zeros 替换为 scipy.sparse.csr_matrix,block_diag 同样支持稀疏输入)。
实现代码(稠密版)
import numpy as np from scipy.linalg import block_diag # 示例数据 A = np.linspace(1, 9, 9).reshape(3, 3) B = np.linspace(10, 18, 9).reshape(3, 3) overlap = 2 # 计算补零尺寸:使 A 占左上,B 占右下,总尺寸 = len(A) + len(B) - overlap n = A.shape[0] total_size = n + n - overlap # 构造零填充块:A 需向下/右补 (n - overlap) 行/列;B 需向上/左补同量 pad_len = n - overlap ZerosA = np.zeros((pad_len, pad_len)) ZerosB = np.zeros((pad_len, pad_len)) # 分子:A 和 B 在各自块对角位置叠加 numerator = block_diag(A, ZerosA) + block_diag(ZerosB, B) # 分母(计数掩码):同结构,用 1 替代实际值 denominator = block_diag(np.ones_like(A), ZerosA) + block_diag(ZerosB, np.ones_like(B)) # 加权平均:仅对 denominator > 0 的位置计算,其余置 0 result = np.divide(numerator, denominator, out=np.zeros_like(numerator), where=denominator!=0) print(result)
输出:
[[ 1. 2. 3. 0. ] [ 4. 7.5 8.5 12. ] [ 7. 10.5 11.5 15. ] [ 0. 16. 17. 18. ]]
✅ 完全匹配预期:(1,1) 处为 A[1,1]=5 与 B[0,0]=10 的平均值 7.5,依此类推。
注意事项与进阶建议
- 通用性扩展:本例假设方阵与对称重叠。若需矩形阵或非对称重叠(如水平重叠 2 列、垂直重叠 1 行),可分别计算行/列方向的 pad_len_row 和 pad_len_col,并改用 scipy.sparse.bmat 或手动拼接子块。
- 稀疏矩阵支持:将 np.zeros 替换为 scipy.sparse.csr_matrix((pad_len, pad_len)),np.ones_like(A) 替换为 scipy.sparse.csr_matrix(np.ones_like(A)),block_diag 会自动返回稀疏矩阵,大幅节省内存。
- 性能提示:对于大规模矩阵,优先使用 scipy.sparse.block_diag 并保持全程稀疏运算;避免 np.where 或 np.divide(..., where=...) 在稀疏场景下转为稠密。
- 边界处理:当前策略对非重叠区直接保留原值(等价于权重 1),符合多数应用场景;如需自定义加权函数(如高斯衰减),可将 denominator 替换为对应权重矩阵。
该方法以极简代码实现了灵活、鲁棒且可扩展的重叠拼接,是构建分块算法、多分辨率分析及分布式矩阵组装的理想基础组件。

















