【问题标题】:How can I average a matrix every nth elements in a vectorized way?如何以矢量化方式平均每第 n 个元素的矩阵?
【发布时间】:2017-09-23 00:11:20
【问题描述】:

在 MATLAB 中,给定一个 36 x 17 矩阵 A,我想平均每列的每 6 个元素,创建一个 6 x 17 矩阵 B。我可以使用以下代码实现它:

A = rand(36, 17);

B = [mean(A(1:6:36,:)); mean(A(2:6:36,:)); mean(A(3:6:36,:)); mean(A(4:6:36,:)); mean(A(5:6:36,:)); mean(A(6:6:36,:))];

虽然语法不是很长,但我想知道是否可以通过更紧凑、更有效的方式(即使用bsxfunarrayfun?)实现相同的结果

【问题讨论】:

  • 您可以重塑为 3d 矩阵并在其中一个维度上取平均值。
  • 我怀疑 arrayfun 会更有效。在大多数情况下,Arrayfun 的效率可能低于循环。

标签: matlab matrix vectorization mean bsxfun


【解决方案1】:

如 cmets 中所述,reshape 基本上将第一个暗淡分为两个,前者的长度为 6 以拥有一个 3D 数组,然后在这两个中的后者中使用 mean,这将成为3D 数组中的第二个暗淡,并最终重塑/挤压2D 输出 -

B = squeeze(mean(reshape(A,6,[],size(A,2)),2))

【讨论】:

    【解决方案2】:

    出于好奇,这也可以通过矩阵乘法来完成(效率接近Divakar's answer,在某些情况下甚至更快):

    N = size(A, 1)/6;
    B = (repmat(eye(6), 1, N)*A)./N;
    

    【讨论】:

    • 也许快一点:repmat(eye(6)/N, N, 1).'*A
    • @LuisMendo:重新排序以删除转置是一个好主意,但是将除法“移入”乘法似乎会造成数值准确性的轻微损失(结果与 Divakar 的结果相差大约机器精度eps,但在除法“外”时完全相等)。
    • 谁说 Divikar 的答案是准确的?
    • 请注意1.1 - (1.1/3 + 1.1/3 + 1.1/3) = 01.1-3.3/3 = eps
    • @m7913d:嗯,Divakar 正在使用内置的mean 函数,我将其作为基本事实。此外,eye(6) 仅包含 0 和 1,无需舍入即可精确表示,但 eye(6)/N 会在矩阵相乘之前从一开始就引入潜在的舍入误差。例如,请注意 sum(ones(1,6))/6 不完全等于 sum(ones(1,6)/6)
    【解决方案3】:

    为了完整起见,您可以使用2D convolution 获得相同的结果,如下所示:

      n = 6; % average every n-th element
      C = zeros(size(A, 1) - n + 1, 1);
      C(1:n:size(A, 1), :) = 1/(size(A, 1) / n);
      B = conv2(A, C, 'valid');
    

    请注意,此结果可能不如 Divakar(以及评论中的烧杯)提出的基于重塑为 3D 的答案有效,但比原始问题更有效。

    【讨论】:

      猜你喜欢
      • 2020-03-25
      • 1970-01-01
      • 2022-12-12
      • 2020-03-20
      • 2021-10-29
      • 1970-01-01
      • 2016-10-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多