如何使用NumPY对缩小功能进行矢量化



给定NumPY中的NxM矩阵,我希望将其向下采样为NxO矩阵(O<<<M(,以便从原始矩阵中等距样本线性插值NxO阵列中的值。

举个例子,考虑一个3x10矩阵:

[
[1  2  3  4  5  6  7  8  9  10]
[10 9  8  7  6  5  4  3  2  1 ]
[4  6  4  6  4  6  4  6  4  6 ]
]

如果我将其向下采样为3x4矩阵,则值可能会这样排列:

1   2   3   4   5   6   7   8   9   10
|---|---|---|---|---|---|---|---|---|
*      *       *      *      
1      2       3      4

通常,给定M个原始元素被下采样为O个新元素,第一个元素应该从(M-1)/(O+1)采样,并且在(M-1)/(O+1)的步骤中获取额外的采样。这可以在上面的图像中看到,其中10个原始元素在元素之间产生9个"间隙"。我们希望将9个"间隙"的距离划分为5个相等的部分(在左右两侧留出相等的空间,每个元素之间的间距相等(。因此,每个新元素的间距为9/5=1.8"间隙":

  • 新元素0=旧元素1.8
  • 新元素1=旧元素3.6
  • 新元素2=旧元素5.4
  • 新元素3=旧元素7.2

使用基本线性插值,我们可以说"元素1.8"是元素2的80%加上元素1 的20%

因此,我的最终矩阵看起来是这样的:

[
[2.8 4.6 6.4 8.2]
[8.2 6.4 4.6 2.8]
[4.4 4.8 5.2 5.6]
]

我考虑过只编写一个函数来计算输出值并使用np.apply_along_axis()方法,但后来我看到这篇StackOverflow帖子说,这样做只是对for循环的一个脆弱的包装,最好将函数矢量化。

那么如何将其矢量化呢?能做到吗?

尝试此功能

def downsample(m, samples):
weights = np.zeros((m.shape[1], samples))
for n in range(samples):
pos = ((m.shape[1] - 1) / (samples + 1)) * (n + 1)
if pos == np.floor(pos):
weights[int(np.floor(pos)), n] = 1
else:
weights[int(np.ceil(pos)), n] = pos - int(np.floor(pos))
weights[int(np.floor(pos)), n] = int(np.ceil(pos)) - pos
return np.matmul(m, weights)

它会根据您描述的插值创建一个权重矩阵,然后将该权重应用于整个矩阵。

最新更新