【问题标题】:How to vectorize a down-scaling function with NumPY?如何使用 NumPY 向量化缩减函数?
【发布时间】:2020-02-26 01:29:20
【问题描述】:

给定 NumPY 中的 NxM 矩阵,我希望将其下采样为 NxO 矩阵 (O

例如,考虑一个 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() 方法,但后来我看到this StackOverflow post 说这样做只是一个脆弱的 for 循环包装器,你最好将你的向量化功能。

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

【问题讨论】:

  • 我赞成这个只是因为不使用 apply_along_axis。

标签: python numpy matrix


【解决方案1】:

试试这个功能

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)

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

【讨论】:

  • 将手动做一些矩阵来验证结果,并尝试阅读并理解代码,但我只是在问题中的示例 3x10 矩阵上对其进行了测试,结果是正确的答案——所以看起来不错:)
  • 刚刚尝试使用相同的 3x10 样本矩阵并下采样到 5 而不是 4,而不是第一行的预期 [2.5, 4, 5.5, 7, 8.5],它返回 [2.5, 0, 5.5, 0, 8.5]。所以当权重是一个精确的整数时会发生一些奇怪的事情
  • 工作就像一个魅力,并阅读了它是如何工作的(并记得我的矩阵乘法从上帝知道多少年前)我还开始使用 np.diag 开发一个稍微更优雅和更快的解决方案计算weights 矩阵,但我还没有完成。如果我弄清楚我正在研究的解决方案,我会接受这一点并添加一个新的答案。快速更新:当我意识到我想错了时,我放弃了我的解决方案。可能有一种更快的方法来生成weights 矩阵,但我所做的并不奏效。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-05
  • 2016-12-07
  • 2018-08-16
  • 1970-01-01
  • 2021-11-26
相关资源
最近更新 更多