MATLAB 分步应用 CUMSUM
MATLAB APPLY CUMSUM IN STEPS
我有 x = 500 X 612 矩阵中的整数数据。我需要一个 500 X 612 矩阵中的新变量 xx 但我需要在 12 列步骤中沿每一行 (500) 应用 cumsum 并像这样应用 cumsum 51 次 --> 500 X (12 X 51) 矩阵。然后我需要一个 for 循环来生成 cumsum 时间序列的 500 行和 12 列的 51 个图。谢谢!
我将改写问题的内容以使正在阅读的人受益。
OP 希望通过将矩阵拆分成一堆列来将矩阵分割成块。 cumsum
分别应用于每一列的每一行,然后连接在一起以构建最终矩阵。因此,给定此源矩阵:
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
并将最终结果拼凑在一起。所以结果如下:
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
。当您在 MATLAB 中重塑某些东西时,它会收集值 按列 并将输入重塑为指定大小的输出。因此,要收集行,我们需要收集 row-wise 因此我们必须转置这个矩阵。接下来,divide_point
告诉您一个块中的一行有多少个元素。因此,我们要构造一个大小为 divide_point x N
的矩阵,其中 divide_point
告诉您我们在一个块的一行中有多少个元素,而 N
是整个行的总数所有块。因为我不想计算有多少(实际上我很懒....),[]
语法是自动推断这个数字,这样我们就可以得到一个重塑的矩阵,尊重总数原始输入中的元素。然后我们对这些列中的每一列执行 cumsum
,然后我们需要 reshape
将其恢复为输入的原始形状。有了这个,我们在 cumsum
结果上再次使用 reshape
,但是为了让它回到你想要的行顺序,我们必须确定转置,因为 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 列的矩阵,每隔一列创建一个块。
我有 x = 500 X 612 矩阵中的整数数据。我需要一个 500 X 612 矩阵中的新变量 xx 但我需要在 12 列步骤中沿每一行 (500) 应用 cumsum 并像这样应用 cumsum 51 次 --> 500 X (12 X 51) 矩阵。然后我需要一个 for 循环来生成 cumsum 时间序列的 500 行和 12 列的 51 个图。谢谢!
我将改写问题的内容以使正在阅读的人受益。
OP 希望通过将矩阵拆分成一堆列来将矩阵分割成块。 cumsum
分别应用于每一列的每一行,然后连接在一起以构建最终矩阵。因此,给定此源矩阵:
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
并将最终结果拼凑在一起。所以结果如下:
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
。当您在 MATLAB 中重塑某些东西时,它会收集值 按列 并将输入重塑为指定大小的输出。因此,要收集行,我们需要收集 row-wise 因此我们必须转置这个矩阵。接下来,divide_point
告诉您一个块中的一行有多少个元素。因此,我们要构造一个大小为 divide_point x N
的矩阵,其中 divide_point
告诉您我们在一个块的一行中有多少个元素,而 N
是整个行的总数所有块。因为我不想计算有多少(实际上我很懒....),[]
语法是自动推断这个数字,这样我们就可以得到一个重塑的矩阵,尊重总数原始输入中的元素。然后我们对这些列中的每一列执行 cumsum
,然后我们需要 reshape
将其恢复为输入的原始形状。有了这个,我们在 cumsum
结果上再次使用 reshape
,但是为了让它回到你想要的行顺序,我们必须确定转置,因为 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 列的矩阵,每隔一列创建一个块。