按列平均每 N 行
Average every N rows by column
我有四个 240x30 的矩阵。我需要计算每 15 行的平均值,并且需要按列计算。所以,最后我应该有 30 列和 16 个值。
因此,例如:
myMatrix = randi(240,30)
这是我目前所拥有的:
averageBins = 15;
meanByBinsMyMatrix = arrayfun(@(i) mean(myMatrix (i:i+averageBins-1)),1:averageBins:length(myMatrix )-averageBins+1)'; % the averaged vectormean()
这似乎有效,但我认为它只对第一列有用。
我如何扩展它以处理每一列?
你可以reshape()
your first dimension a to 15-by-n matrix, leaving the columns as third dimension. Then take the mean over the first dimensions, i.e. your blocks of n
rows. Since this will result in a 1x16x30
matrix in your case, squeeze()
出最后一个维度。
n = 15;
A = rand(240,30);
B = reshape(A,[n, size(A,1)/n, size(A,2)]); %crashes for size(A,1)/n != integer
C = squeeze(mean(B,1)); % Calculate the mean over the first dimension
多维度reshape()
的简短介绍。
创建一个小矩阵,比如 magic(4)
,用于可视化:
A = magic(4)
A =
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
这是一个四列矩阵。现在,如果我们将它重新整形为 2x2x4 矩阵,我们的维度会去哪里?让我们试试吧:
B = reshape(A,[2,2,4])
B(:,:,1) =
16 9
5 4
B(:,:,2) =
2 7
11 14
B(:,:,3) =
3 6
10 15
B(:,:,4) =
13 12
8 1
发生了什么事? A
的第一列包含 [16;5;9;4]
。 B
的第一个“页面”,即第三维度上的第一个条目,正好包含这些数字!
reshape()
按 列 工作,这意味着它“遍历”初始矩阵 (1,1)->(2,1)-> (3,1) 等等,直到到达第一列的末尾。然后它开始读取 (1,2)->(2,2)->(3,2) 等
至于存储部分:MATLAB 以相同的顺序存储它们,因此按列存储。当它填满一个维度时,它会将下一个维度索引增加1并继续填充。因此,A
的 1x4 第一列首先存储为 [16;5]
,然后填充第二列,形成 B(:,:,1) = [16 9;5 4]
的第一页,即它开始填充第一列的第二列页。现在第一页已满,A
的第二列以同样的方式放入 B
的第二页,第三列进入第三页,依此类推,直到A
中的所有元素都被复制。
注意:这就是为什么reshape
的“size”参数如此重要,它告诉程序何时开始下一个维度。您的尺寸的乘积,即元素的数量,在此操作期间不能更改!
在原始情况下执行此操作后,您最终会得到一个 15×16×30 矩阵。这意味着您有 30 页,您的原始列,每列 16 列,15 行的块数,是每个组中的元素数。
然后 mean(B,1)
告诉 mean
取 第一个 维度的平均值,这是每个块中的元素,以及所有元素块和页面。
唯一剩下的小事情是 MATLAB 默认情况下不会去除非尾随单维度,因此您最终得到一个 1×16×30 矩阵。 squeeze()
,最后,去掉所有单例维度,留下一个 16×30 的矩阵,其中包含相应 row/column 位置的每个 15 个元素块的平均值。
您可以使用 splitapply
来计算每组行的平均值。即使行数不是组大小的倍数(最后一组的行数较少),这也有效:
result = splitapply(@(x)mean(x,1), myMatrix, floor((0:size(myMatrix,1)-1)/averageBins).'+1);
我有四个 240x30 的矩阵。我需要计算每 15 行的平均值,并且需要按列计算。所以,最后我应该有 30 列和 16 个值。
因此,例如:
myMatrix = randi(240,30)
这是我目前所拥有的:
averageBins = 15;
meanByBinsMyMatrix = arrayfun(@(i) mean(myMatrix (i:i+averageBins-1)),1:averageBins:length(myMatrix )-averageBins+1)'; % the averaged vectormean()
这似乎有效,但我认为它只对第一列有用。 我如何扩展它以处理每一列?
你可以reshape()
your first dimension a to 15-by-n matrix, leaving the columns as third dimension. Then take the mean over the first dimensions, i.e. your blocks of n
rows. Since this will result in a 1x16x30
matrix in your case, squeeze()
出最后一个维度。
n = 15;
A = rand(240,30);
B = reshape(A,[n, size(A,1)/n, size(A,2)]); %crashes for size(A,1)/n != integer
C = squeeze(mean(B,1)); % Calculate the mean over the first dimension
多维度reshape()
的简短介绍。
创建一个小矩阵,比如 magic(4)
,用于可视化:
A = magic(4)
A =
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
这是一个四列矩阵。现在,如果我们将它重新整形为 2x2x4 矩阵,我们的维度会去哪里?让我们试试吧:
B = reshape(A,[2,2,4])
B(:,:,1) =
16 9
5 4
B(:,:,2) =
2 7
11 14
B(:,:,3) =
3 6
10 15
B(:,:,4) =
13 12
8 1
发生了什么事? A
的第一列包含 [16;5;9;4]
。 B
的第一个“页面”,即第三维度上的第一个条目,正好包含这些数字!
reshape()
按 列 工作,这意味着它“遍历”初始矩阵 (1,1)->(2,1)-> (3,1) 等等,直到到达第一列的末尾。然后它开始读取 (1,2)->(2,2)->(3,2) 等
至于存储部分:MATLAB 以相同的顺序存储它们,因此按列存储。当它填满一个维度时,它会将下一个维度索引增加1并继续填充。因此,A
的 1x4 第一列首先存储为 [16;5]
,然后填充第二列,形成 B(:,:,1) = [16 9;5 4]
的第一页,即它开始填充第一列的第二列页。现在第一页已满,A
的第二列以同样的方式放入 B
的第二页,第三列进入第三页,依此类推,直到A
中的所有元素都被复制。
注意:这就是为什么reshape
的“size”参数如此重要,它告诉程序何时开始下一个维度。您的尺寸的乘积,即元素的数量,在此操作期间不能更改!
在原始情况下执行此操作后,您最终会得到一个 15×16×30 矩阵。这意味着您有 30 页,您的原始列,每列 16 列,15 行的块数,是每个组中的元素数。
然后 mean(B,1)
告诉 mean
取 第一个 维度的平均值,这是每个块中的元素,以及所有元素块和页面。
唯一剩下的小事情是 MATLAB 默认情况下不会去除非尾随单维度,因此您最终得到一个 1×16×30 矩阵。 squeeze()
,最后,去掉所有单例维度,留下一个 16×30 的矩阵,其中包含相应 row/column 位置的每个 15 个元素块的平均值。
您可以使用 splitapply
来计算每组行的平均值。即使行数不是组大小的倍数(最后一组的行数较少),这也有效:
result = splitapply(@(x)mean(x,1), myMatrix, floor((0:size(myMatrix,1)-1)/averageBins).'+1);