我有 x = 500 X 612 矩阵中的整数数据。我需要一个 500 X 612 矩阵中的新变量 xx 但我需要在 12 列步骤中沿每行 (500) 应用 cumsum 并像这样应用 cumsum 51 次 --> 500 X (12 X 51) 矩阵。然后我需要一个 for 循环来生成 cumsum 时间序列的 500 行和 12 列的 51 个图。谢谢你!
1 回答
我将重新表述问题所要求的内容,以使正在阅读的人受益。
OP 希望通过将矩阵拆分成一堆列来将矩阵分割成块。Acumsum
分别应用于每一行的每一列,然后连接在一起以构建最终矩阵。因此,给定这个源矩阵:
x =
1 2 3 4 5 6 7 8 9 10 11 12
13 14 15 16 17 18 19 20 21 22 23 24
假设我们希望按第 3、6、9 和 12 列分割矩阵,我们将有四个块可供使用。我们cumsum
分别对这些块中的每一个进行 a 并将最终结果拼凑在一起。所以结果如下:
xx =
1 3 6 4 9 15 7 15 24 10 21 33
13 27 42 16 33 51 19 39 60 22 45 69
首先,您需要确定要将矩阵分解为多少列。在您的情况下,我们希望将矩阵分割为 4 个块:第 1 - 3 列、第 4 - 6 列、第 7 - 9 列和第 10 - 12 列。因此,我将使用reshape
这个矩阵,以便每一列都是此矩阵中的块中的单个行。然后我们应用cumsum
这个重塑的矩阵,然后我们将它重塑回原来的样子。
因此,请执行以下操作:
num_chunks = 4; %// Columns 3, 6, 9, 12
divide_point = size(x,2) / num_chunks; %// Determine how many elements are in a row for a cumsum
x_reshape = reshape(x.', divide_point, []); %// Get reshaped matrix
xy = cumsum(x_reshape); %// cumsum over all columns individually
xx = reshape(xy, size(x,2), size(x,1)).'; %// Reconstruct matrix
在第三行代码中,x_reshape = reshape(x.', divide_point, []);
可能看起来有点吓人,但实际上并没有那么糟糕。我必须先转置矩阵,因为您想要获取块的每一行并将它们放入单独的列中,以便我们可以cumsum
对每一列执行 a。当您在 MATLAB 中重塑某些东西时,它会按列收集值并将输入重塑为指定大小的输出。因此,要收集行,我们需要逐行收集,因此我们必须转置这个矩阵。接下来,divide_point
告诉您我们在一个块中的单行有多少个元素。因此,我们想要构建一个大小为 的矩阵,divide_point x N
告诉divide_point
您我们在一个块的一行中有多少个元素,并且N
是所有块的总行数。因为我不想计算有多少(实际上我相当懒惰......),所以[]
语法是自动推断这个数字,以便我们可以得到一个尊重原始输入中元素总数的重构矩阵. 然后我们对这些列中的每一列执行cumsum
,然后我们需要将reshape
其恢复为输入的原始形状。有了这个,我们reshape
再次对cumsum
结果使用,但为了让它回到你想要的行顺序,我们必须确定转置,因为reshape
它以列优先顺序取值,然后重新转置该结果。
我们得到:
xx =
1 3 6 4 9 15 7 15 24 10 21 33
13 27 42 16 33 51 19 39 60 22 45 69
通常,要对一行求和的元素总数需要被矩阵包含的列总数整除。例如,鉴于上述情况,如果您尝试将此矩阵分割为 5 个块,您肯定会收到错误,因为要cumsum
超过的行数不是对称的。
再举一个例子,假设我们想将矩阵分成 6 个块。因此,通过设置num_chunks = 6
,我们得到:
xx =
1 3 3 7 5 11 7 15 9 19 11 23
13 27 15 31 17 35 19 39 21 43 23 47
您可以看到cumsum
每隔一列重新开始,因为我们需要 6 个块,并且要获得 6 个块和 12 列的矩阵,每隔一列创建一个块。