【问题标题】:Sum every n rows of matrix每n行矩阵求和
【发布时间】:2013-09-18 17:41:18
【问题描述】:

有什么方法可以总结矩阵中每组三行的列值?
我可以手动总结三行。

例如

% matrix is the one I wanna store the new data.
% data is the original dataset.
matrix(1,1:end) = sum(data(1:3, 1:end))
matrix(2,1:end) = sum(data(4:6, 1:end))
...

但如果数据集很大,这将行不通。
有没有什么方法可以在没有循环的情况下自动执行此操作?

【问题讨论】:

  • 对我来说看起来不像是骗子,因为我不清楚一个简单的重塑就可以解决问题。
  • 我不同意,一个单一的重塑然后求和和挤压就可以了。与另一个问题的唯一区别是它是 2D 与 1D。这是一个解决方案:squeeze(sum(reshape(a,size(a,2), 3,[])))
  • 但就 Amro 的回答而言,这个问题是值得的……+1 Amro

标签: matlab matrix sum row


【解决方案1】:

Prashant 之前回答得很好,但我有一个简单的修改:

fl = filterLength;
A = yourVector (where mod(A,fl)==0)
sum(reshape(A,fl,[]),1).'/fl;

即使在 fl==1(原始值)时,也有使行运行的“,1”。 我在这样的 for 循环中运行它时发现了这一点:

... read A ...
% Plot data
hold on;

averageFactors = [1 3 10 30 100 300 1000];
colors = hsv(length(averageFactors));
clear legendTxt;


for i=1:length(averageFactors)
% ------ FILTERING ----------
clear Atrunc;
clear ttrunc;
clear B;
fl = averageFactors(i); % filter length
Atrunc = A(1:L-mod(L,fl),:);
ttrunc = t(1:L-mod(L,fl),:);

B = sum(reshape(Atrunc,fl,[]),1).'/fl;
tB = sum(reshape(ttrunc,fl,[]),1).'/fl;
length(B)
plot(tB,B,'color',colors(i,:) )
%kbhit ()
endfor

【讨论】:

    【解决方案2】:

    还有其他四种方法:

    1. 必填for-loop:

      % for-loop over each three rows
      matrix = zeros(size(data,1)/3, size(data,2));
      counter = 1;
      for i=1:3:size(data,1)
          matrix(counter,:) = sum(data(i:i+3-1,:));
          counter = counter + 1;
      end
      
    2. 使用mat2cell 进行平铺:

      % divide each three rows into a cell
      matrix = mat2cell(data, ones(1,size(data,1)/3)*3);
      
      % compute the sum of rows in each cell
      matrix = cell2mat(cellfun(@sum, matrix, 'UniformOutput',false));
      
    3. 使用第三维度(基于this):

      % put each three row into a separate 3rd dimension slice
      matrix = permute(reshape(data', [], 3, size(data,1)/3), [2 1 3]);
      
      % sum rows, and put back together
      matrix = permute(sum(matrix), [3 2 1]);
      
    4. 使用accumarray

      % build array of group indices [1,1,1,2,2,2,3,3,3,...]
      idx = floor(((1:size(data,1))' - 1)/3) + 1;
      
      % use it to accumulate rows (appliead to each column separately)
      matrix = cell2mat(arrayfun(@(i)accumarray(idx,data(:,i)), 1:size(data,2), ...
          'UniformOutput',false));
      

    当然,到目前为止的所有解决方案都假设行数可以被3 整除。

    【讨论】:

    • 答案真的很有帮助。他们每个人都是一个很好的学习榜样。欣赏这一点。 @Amro
    • 其实我注意到还有一个问题。如果行数不可整除怎么办。不知道怎么解决。我只是删除了一些数据以使数字可整除。你有经验的想法吗?阿姆罗?
    • @ChrisSu:我添加了第四个解决方案:一个简单的 for 循环。你不应该这么快就丢弃它,它也比较快(感谢 MATLAB 中的 JIT 编译)
    • @ChrisSu:在这种情况下,只需像以前一样处理data(1:3*N,:) where N = floor(size(data,1)/3),然后添加剩下的任何内容(剩余一两行的总和)。当然,所有这些解决方案都可以推广到任何X 行组(我们上面的 X=3)
    • 第 4 个解决方案很好。循环是可以的,但它仍然是一个 C 或 java 的头脑来编程。由于我是 matlab 新手,我想训练自己更好地理解本质。关于不可分割的问题,我认为你是对的。可能预先计算 N 会比我的解决方案更好。感谢您的详细回答。
    【解决方案3】:

    这个单行reshapes 使特定单元格所需的所有值都在一个列中,然后sum,然后reshapes 回到预期的形状。

    reshape(sum(reshape(data, 3, [])), [], size(data, 2))
    

    如果您想将不同数量的行加在一起,可以更改裸露的3。您需要确保每组中的行数平均分配。

    【讨论】:

    • 哇~这个很酷。它运作良好! Matlab 摇滚!非常感谢。 @Prashant
    • 如果对您有帮助,您可以accept the answer。 :) 它也给你代表!
    【解决方案4】:

    将矩阵分成三部分并将它们相加:

    matrix = data(1:3:end, :) + data(2:3:end, :) + data(3:3:end, :);
    

    如果size(data,1) 不是三的倍数,这将产生错误,因为这三个部分的大小不同。如果适合您的数据,您可以通过截断 data 或在末尾附加一些零来解决此问题。

    您还可以使用 reshape 和 3D 数组来做一些花哨的事情。但我更喜欢上面的(除非你需要用变量替换3...)

    【讨论】:

    • 是的。我明白你的意思了。如果所需的零件很小,则此方法有效。实际上,它可能会长到 140 件。在那种情况下,这种方式是行不通的。有更好的主意吗?
    猜你喜欢
    • 2017-11-16
    • 2015-01-15
    • 2015-10-19
    • 2013-11-30
    • 1970-01-01
    • 1970-01-01
    • 2011-05-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多