How can I count every n columns of each row in a matrix?

So, I have a monthly return matrix in the form of 1000x300. I would like to take the average of every 12 columns for each row of the return matrix in order to give me an annual income, which will ultimately lead to a 1000x25 matrix.

How can I do this in matlab?

Thanks to some quick search, I think I can somehow use the reshape function, but it's hard for me to figure out how to implement it in my code loop.

So far this is my attempt.

for i = 1:25 Strategy1.MeanReturn(:,i) = mean(Data.Return(:,i+1):Data.Return(:,i*12+1)); end 

Fyi, +1 is, because I ignore the first column of the matrix.

But this leads me to obtain a singular value of NaN.

+5
source share
4 answers

try the following:

 B = zeros(1000,25); A = rand(1000,300); for i = 1:25 B(:,i) = mean(A(:,(i-1)*12+1:i*12),2); end 

I just tested it by building the sum of them, and it worked.

+5
source

You can add the necessary submatrices according to the first size of the 3D array, then perform an average value for this size and squeeze the resulting singlet size:

 x = rand(10,20); % example data. 1000x300 in your case N = 4; % group size. 12 in your case y = reshape(x.', N, size(x,2)/N, []); result = squeeze(mean(y,1)).'; 
+5
source

Cycles are not always slow. In fact, tests performed by Mathworks showed that loop speed improved by 40% as a result of the new and improved Execution Engine (JIT)

The average performance improvement in all tests was 40%. tests consisted of code that used a number of MATLAB products. Although not all applications ran faster with the redesign, most of them applications in R2015b are at least 10% faster than in R2015a.

and

The performance benefit of JIT compilation is most when MATLAB code is executed again and can reuse compiled code. This happens in normal cases, such as for-loops or when applications run extra time in a MATLAB session.


A quick test of three solutions:

 %% bushmills answer, saved as bushmills.m function B = bushmills(A,N) B = zeros(size(A,1),size(A,2)/N); for i = 1:size(A,2)/NB(:,i) = mean(A(:,(i-1)*12+1:i*12),2); end end A = rand(1000,300); N = 12; %% Luis Mendo answer: lmendo = @(A,N) squeeze(mean(reshape(x.', N, size(x,2)/N, []))).'; %% Divakar answer: divakar = @(A,N) reshape(mean(reshape(A,size(A,1),N,[]),2),size(A,1),[]); b = @() bushmills(A,N); l = @() lmendo(A,N); d = @() divakar(A,N); sprintf('Bushmill: %d\nLuis Mendo: %d\nDivakar: %d', timeit(b), timeit(l), timeit(d)) ans = Bushmill: 1.102774e-03 Luis Mendo: 1.611329e-03 Divakar: 1.888878e-04 sprintf('Relative to fastest approach:\nDivakar: %0.5f\nBushmill: %0.5f\nLuis Mendo: %0.5f', 1, tb/td, tl/td) ans = Relative to fastest approach: Divakar: 1.00000 Bushmill: 5.34464 Luis Mendo: 10.73969 

The loopback approach (with pre-distribution) is about 40% faster than squeeze(mean(reshape(...))) . Divakar's solution is a mile away.


It may differ for other values โ€‹โ€‹of A and N , but I have not tested everything.

+5
source

Using the philosophy that reshape almost zero cost , an approach is used here that basically uses mean :

 % A is the input array of shape (1000,300) N = 12; %// Group size M = size(A,1); out = reshape(mean(reshape(A,M,N,[]),2),M,[]); 

It would be interesting to see how it works against the new JIT !

+5
source

All Articles