按列平均每N行 [英] Average every N rows by column

查看:64
本文介绍了按列平均每N行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有四个240x30的矩阵.我需要计算每15行的平均值,并且需要按列进行计算.因此,最后我应该有30列,包含16个值.

例如,

  myMatrix = randi(240,30) 

这是我到目前为止所拥有的:

  averageBins = 15;meanByBinsMyMatrix = arrayfun(@(i)均值(myMatrix(i:i + averageBins-1)),1:averageBins:length(myMatrix)-averageBins + 1)';平均vectormean()的百分比 

这似乎在起作用,但我认为它仅在第一列中起作用.如何将其扩展到每一列?

解决方案

您可以 reshape() 您的第一个维度是15到n的矩阵,而列则是第三个维度.然后取第一个维度的平均值,即您的 n 行的块.由于这会导致您生成 1x16x30 矩阵,因此 squeeze() 移出最后一个尺寸.

  n = 15;A = rand(240,30);B =重塑(A,[n,size(A,1)/n,size(A,2)]);大小(A,1)/n的%!!=整数C =挤压(均值(B,1));%计算第一维的平均值 


在多个维度上对 reshape()的简短介绍.

为可视化创建一个小的矩阵,例如 magic(4):

  A =魔法(4)A =16 2 3 135 11 10 89 7 6 124 14 15 1 

这是一个四列矩阵.现在,如果我们将其重塑为2x2x4矩阵,那么尺寸在哪里呢?试试吧:

  B =重塑(A,[2,2,4])B(:,:,1)=16 95 4B(:,:,2)=2 711 14B(:,:,3)=3 610 15B(:,:,4)=13 128 1 

发生了什么事? A 的第一列包含 [16; 5; 9; 4] . B 的第一个页面",即第三维的第一个条目,正好包含这些数字!

reshape() column-wise 的方式工作,这意味着它可以行走"或行走".通过初始矩阵前进(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 的参数非常重要,它告诉程序何时从下一个维度开始.您大小的乘积(即元素数量)在此操作期间无法更改!

在原始情况下执行此操作后,最终得到15 x 16 x 30矩阵.这意味着您有30页,即原始列,每列16列,即15行的块数,即每组中的元素数.
然后, mean(B,1)告诉 mean 取平均值 first ,这是您每个元素中的要素块,以及所有块和页面上的块.

剩下的唯一小事是MATLAB默认情况下不会剥离非跟踪单例尺寸,因此最终得到的是1×16×30矩阵.最后, squeeze()去除所有单例维度,为您提供16 x 30的矩阵,其中包含相应行/列位置中15个元素的每个块的平均值.

I have four matrices that are 240x30. I need to calculate an average for every 15 rows and I need to do this by column. So, in the end I should have 30 columns with 16 values.

So, for instance:

myMatrix = randi(240,30)

And this is what I have so far:

averageBins = 15;
meanByBinsMyMatrix = arrayfun(@(i) mean(myMatrix (i:i+averageBins-1)),1:averageBins:length(myMatrix )-averageBins+1)'; % the averaged vectormean()

This seems to be working but I think it only does the job for the first column. How can I extend this to work over each column?

解决方案

You can 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() out the last dimension.

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


A short introduction to reshape() in multiple dimensions.

Create a small matrix, say magic(4), for visualisation:

A = magic(4)
A =
    16     2     3    13
     5    11    10     8
     9     7     6    12
     4    14    15     1

This is a four column matrix. Now, if we reshape it to a 2x2x4 matrix, where do our dimensions go? Let's try it:

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

What happened? The first column of A contains [16;5;9;4]. The first "page", which is the first entry on the third dimension, of B contains exactly these numbers!

reshape() works column-wise, meaning that it "walks" through the initial matrix going (1,1)->(2,1)->(3,1) etc, until the end of the first column is reached. Then it starts reading at (1,2)->(2,2)->(3,2) etc.
As to the storing part: MATLAB stores them in the same order, thus column wise. When it has filled up a dimension, it will increase the next dimension index by 1 and keep on filling. Thus, the 1x4 first column of A gets stored as [16;5] first, then the second column is filled, making the first page of B(:,:,1) = [16 9;5 4], i.e. it started filling the second column of the first page. Now that the first page is full, the second column of A gets put into the second page of B in the same way, the third column goes to the third page and so on and so forth, until all elements in A are copied.

Note: this is why the "size" parameter of reshape is so important, it tells the program when to start in the next dimension. The product of your sizes, i.e. the number of elements, cannot change during this operation!

After doing this in the original case, you end up with a 15-by-16-by-30 matrix. Meaning that you have 30 pages, your original columns, which 16 columns each, the number of blocks, of 15 rows, being the number of elements in each group.
Then mean(B,1) tells mean to take the mean over the first dimension, which are the elements in each of your blocks, and that across all blocks and pages.

The only minor thing left is that MATLAB doesn't strip off non-trailing singleton dimensions by default, so you end up with a 1-by-16-by-30 matrix. squeeze(), finally, strips out all the singleton dimensions, leaving you with a 16-by-30 matrix, containing the average of each block of 15 elements in the corresponding row/column location.

这篇关于按列平均每N行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆