【发布时间】:2020-01-17 07:31:07
【问题描述】:
我有一个大小为2500 x 500 的矩阵A。我想对每 10 列求和,并将结果作为矩阵 B,大小为 2500 x 50。即B的第一列是A的前10列之和,B的第二列是A的后10列之和,以此类推。
如果没有for 循环,我该怎么做?因为我必须这样做数百次,而且使用 for 循环这样做非常耗时。
【问题讨论】:
我有一个大小为2500 x 500 的矩阵A。我想对每 10 列求和,并将结果作为矩阵 B,大小为 2500 x 50。即B的第一列是A的前10列之和,B的第二列是A的后10列之和,以此类推。
如果没有for 循环,我该怎么做?因为我必须这样做数百次,而且使用 for 循环这样做非常耗时。
【问题讨论】:
首先,我们“阻止重塑”A,这样我们就有了所需的列数。因此,we shamelessly steal the code from the great Divakar,并付出一些最小的努力来概括它。然后,我们只需要沿第二个轴求和,并重塑为原始形式。
这是一个需要汇总五列的示例:
% Sample input data
A = reshape(1:100, 10, 10).'
[r, c] = size(A);
% Number of columns to be summed
n_cols = 5;
% Block reshape to n_cols, see https://stackoverflow.com/a/40508999/11089932
B = reshape(permute(reshape(A, r, n_cols, []), [1, 3, 2]), [], n_cols);
% Sum along second axis
B = sum(B, 2);
% Reshape to original form
B = reshape(B, r, c / n_cols)
这是输出:
A =
1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27 28 29 30
31 32 33 34 35 36 37 38 39 40
41 42 43 44 45 46 47 48 49 50
51 52 53 54 55 56 57 58 59 60
61 62 63 64 65 66 67 68 69 70
71 72 73 74 75 76 77 78 79 80
81 82 83 84 85 86 87 88 89 90
91 92 93 94 95 96 97 98 99 100
B =
15 40
65 90
115 140
165 190
215 240
265 290
315 340
365 390
415 440
465 490
希望有帮助!
【讨论】:
这可以通过splitapply 完成。这种方法的一个优点是它即使组大小不除列数(最后一组更小)也可以工作:
A = reshape(1:120, 12, 10).'; % example 10×12 data (borrowed from HansHirse)
n_cols = 5; % number of columns to sum over
result = splitapply(@(x)sum(x,2), A, ceil((1:size(A,2))/n_cols));
在这个例子中,
A =
1 2 3 4 5 6 7 8 9 10 11 12
13 14 15 16 17 18 19 20 21 22 23 24
25 26 27 28 29 30 31 32 33 34 35 36
37 38 39 40 41 42 43 44 45 46 47 48
49 50 51 52 53 54 55 56 57 58 59 60
61 62 63 64 65 66 67 68 69 70 71 72
73 74 75 76 77 78 79 80 81 82 83 84
85 86 87 88 89 90 91 92 93 94 95 96
97 98 99 100 101 102 103 104 105 106 107 108
109 110 111 112 113 114 115 116 117 118 119 120
result =
15 40 23
75 100 47
135 160 71
195 220 95
255 280 119
315 340 143
375 400 167
435 460 191
495 520 215
555 580 239
【讨论】: