我想将data
变量拆分为不同的变量a
b
和c
,然后将mean
应用于垃圾箱(第一维)。有没有办法在速度上大幅度提高(例如1倍数量级)此代码?欢迎一般反馈
data=rand(20,1000); %generate data
bins=[5 10 5]; %given size of bins
start_bins=cumsum([1 bins(1:end-1)]);
end_bins=cumsum([bins]);
%split the data into 3 cell arrays and apply mean in 1st dimension
binned_data=cellfun(@(x,y) mean(data(x:y,:),1),num2cell(start_bins),num2cell(end_bins),'uni',0);
%data (explicitly) has be stored into different variables
[a,b,c]=deal(binned_data{:});
whos a b c
Name Size Bytes Class Attributes
a 1x1000 8000 double
b 1x1000 8000 double
c 1x1000 8000 double
答案 0 :(得分:3)
可以在分割之前应用均值,从而将数据简化为向量,然后可以使用accumarray
:
binned_data = accumarray(repelem(1:numel(bins), bins).', mean(data,2), [], @(x){x.'});
accumarray
1 不适用于矩阵数据。但是您可以使用sparse
,它会自动累积与相同索引对应的数据值:
ind_rows = repmat(repelem((1:numel(bins)).', bins), 1, size(data,2));
ind_cols = repmat(1:size(data,2), size(data,1), 1);
binned_data = sparse(ind_rows, ind_cols, data);
binned_data = bsxfun(@rdivide, binned_data, bins(:));
binned_data = num2cell(binned_data, 2).';
但是splitapply
确实如此。参见@Wolfie's answer。
答案 1 :(得分:3)
您可以使用矩阵乘法:
r = 1:numel(bins);
result = (r.' == repelem(r,bins)) * data .* (1./bins(:));
如果要将输出作为单元格:
result = num2cell(result,2);
对于大型矩阵,最好使用稀疏矩阵:
result = sparse(r.' == repelem(r,bins)) * data .* (1./bins(:));
注意:在早期版本的MATLAB中,您应该使用bsxfun
:
result = bsxfun(@times,bsxfun(@eq, r.',repelem(r,bins)) * data , (1./bins(:)))
这是Octave中三种建议方法计时的结果:
矩阵乘法:
0.00197697 seconds
Accumarray:
0.00465298 seconds
Cellfun:
0.00718904 seconds
编辑: 对于200 x 100000矩阵:
矩阵乘法:
0.806947 seconds sparse: 0.2331 seconds
Accumarray:
0.0398011 seconds
Cellfun:
0.386079 seconds
答案 2 :(得分:3)
您可以使用splitapply
(accumarray
的友善小弟弟):
% Your example
data = rand(20,1000); % generate data
bins = [5 10 5]; % given size of bins
% Calculation
bins = repelem(1:numel(bins), bins).'; % Bin sizes to group labels
binned_data = splitapply( @mean, data, bins ); % splitapply for calculation
binned_data
的行是您的a
,b
和c
。
答案 3 :(得分:1)
您还可以使用一个简单的for循环,在这种情况下,我看不出另一个函数可以更快。函数end
在任何情况下都必须读取每个值,以便...
mean
我不会将单元格拆分为多个变量,因为一个单元格正是为此目的而设计的。