所以我有一个月回报矩阵,形式为1000x300。我想获取返回矩阵中每行的每12列的平均值,以给出年度回报,最终将产生1000x25矩阵。
我将如何在Matlab中执行此操作?
通过一些快速搜索,我相信我可以以某种方式使用重塑功能,但我无法弄清楚如何在我的代码循环中实现它。
到目前为止,这是我的尝试。
for i = 1:25
Strategy1.MeanReturn(:,i) = mean(Data.Return(:,i+1):Data.Return(:,i*12+1));
end
Fyi,+1就在那里,因为我忽略了矩阵的第一列。
但这导致我获得单一的NaN值。
答案 0 :(得分:5)
试试这个:
B = zeros(1000,25);
A = rand(1000,300);
for i = 1:25
B(:,i) = mean(A(:,(i-1)*12+1:i*12),2);
end
我只是通过构建一个和它来测试它并且它有效。
答案 1 :(得分:5)
您可以沿3D阵列的第一维堆叠所需的子矩阵,然后沿该维度进行平均,并挤出生成的单个维度:
findNb n = n ^ 2 * (n + 1) ^ 2 / 4
答案 2 :(得分:5)
循环并不总是很慢。实际上,Mathworks执行的测试表明,由于新的Execution Engine (JIT)
,循环速度提高了40%所有测试的平均性能提升为40%。测试 由使用一系列MATLAB产品的代码组成。虽然没有 通过重新设计,所有应用程序运行得更快,其中大部分都是如此 R2015b的应用程序比R2015a快至少10%。
和
当MATLAB时,JIT编译的性能优势最大 代码执行了额外的次数,可以重用已编译的代码。 这种情况发生在常见情况下,例如for循环或应用程序 在MATLAB会话中运行其他时间
三种解决方案的快速基准:
%% 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)/N
B(:,i) = mean(A(:,(i-1)*12+1:i*12),2);
end
end
A = rand(1000,300); N = 12;
%% Luis Mendo's answer:
lmendo = @(A,N) squeeze(mean(reshape(x.', N, size(x,2)/N, []))).';
%% Divakar's 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
循环方法(使用预分配)比squeeze(mean(reshape(...)))
解决方案快约40%。迪瓦卡的解决方案胜过一英里。
A
和N
的其他值可能会有所不同,但我还没有对所有值进行测试。
答案 3 :(得分:5)
使用reshape
is virtually zero cost的哲学,这是一种基本上只使用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,[]);
看一下它对新的JIT
!