基于Python的向量滑动窗口矩阵乘法及结果平均实现问题
滑动窗口矩阵乘法的结果汇总与平均矩阵构建
问题核心
给定1×N的一维数组与n×n矩阵(n<N),对数组执行步长为1的滑动窗口操作:每个窗口取1×n分段与矩阵相乘得到1×n结果,最终要将所有窗口的输出汇总为1×N数组,且每个位置的结果为所有覆盖它的窗口输出的平均值。
一、平均操作的二维权重矩阵构建
以n=3为例的直观说明
假设N=5,滑动窗口共生成3组1×3的输出。我们可以先将这些输出映射到一个3×5的临时矩阵,每个窗口的输出仅填充到其覆盖的位置,其余位置为0:
# 窗口1(覆盖位置0-2)输出:[a0,a1,a2] [a0, a1, a2, 0, 0] # 窗口2(覆盖位置1-3)输出:[b0,b1,b2] [0, b0, b1, b2, 0] # 窗口3(覆盖位置2-4)输出:[c0,c1,c2] [0, 0, c0, c1, c2]
接下来需要一个计数数组记录每个位置被窗口覆盖的次数:[1,2,3,2,1]。将临时矩阵按列求和后,再除以计数数组对应位置的数值,即可得到最终的平均结果。
通用化的权重矩阵构建
对于任意n和N,计数数组的规律为:
- 前n-1个位置:第i个位置(从0开始)的计数为
i+1 - 中间
N-2*(n-1)个位置:计数恒为n - 后n-1个位置:第j个位置(从
N-n+1到N-1)的计数为N-j
如果要将平均操作转化为矩阵乘法形式,可以构建一个N×(N-n+1)的权重矩阵W:
- W[i][k] = 1/count[i],当第k个窗口覆盖位置i时;否则为0
- count[i]为位置i的覆盖次数(即上述计数数组的元素)
最终结果可通过W × 窗口输出矩阵的重组形式计算,但实际工程中直接按列求和再除以计数的实现效率更高。
二、特殊卷积视角的解读
该操作可视为一种变种卷积:
- 输入:1×N一维数组
- 核:n×n矩阵
- 步长:1
- 与普通卷积的区别:普通卷积是输入窗口与核做点积(1×n · n×1),这里是输入窗口与核做矩阵乘法(1×n · n×n)得到1×n输出,等价于每个输出位置是输入窗口与核的对应行做点积。
从卷积视角看,汇总的本质是:每个输出位置i,取所有包含i的窗口中,该窗口输出的对应偏移位置元素的平均值。比如位置1会被窗口1的第1个元素、窗口2的第0个元素覆盖,取二者的平均。
三、简单实现示例(伪代码)
import numpy as np def sliding_mat_mult_avg(x, kernel): N = len(x) n = kernel.shape[0] num_windows = N - n + 1 result = np.zeros(N, dtype=np.float64) coverage_count = np.zeros(N, dtype=np.int32) for idx in range(num_windows): # 提取当前滑动窗口 window = x[idx:idx+n] # 执行矩阵乘法 window_output = window @ kernel # 累加结果到对应位置 result[idx:idx+n] += window_output # 更新覆盖计数 coverage_count[idx:idx+n] += 1 # 计算平均 result /= coverage_count return result
内容的提问来源于stack exchange,提问作者Rana
相关产品推荐
相关产品推荐

