Can I get rid of this for loop?

2 次查看(过去 30 天)
I have a matrix that has 3 columns that consist of -1, 0, and 1 (let's call them the "level columns"), and a fourth column that contains real numbers (call it the "data column"). For the level columns, I want to find the average of the "-1", "0", and "1" terms in the data column. So for the following matrix,
-1 -1 0 837
-1 0 -1 880
-1 0 1 879
-1 1 0 864
0 -1 -1 834
0 -1 1 833
0 0 0 874
0 0 0 875
0 0 0 876
0 1 -1 860
0 1 1 859
1 -1 0 829
1 0 -1 872
1 0 1 874
1 1 0 856
the -1 average for column 1 would be 865. Is there a way that I can do that all at once, for each level column, and each level column value? Right now, I loop over the level columns and do this:
[mean(testMat(testMat(:,col) == -1,4)) mean(testMat(testMat(:,col) == 0,4)) mean(testMat(testMat(:,col) == 1,4))]
Is there a better way?
Thanks!

采纳的回答

Stephen23
Stephen23 2016-3-18
编辑:Stephen23 2016-3-18
You cannot get rid of the for loop, but you can hide it inside a cellfun call. Note that my answer works for any number of columns, unlike the other solutions.
M = [...
-1 -1 0 837
-1 0 -1 880
-1 0 1 879
-1 1 0 864
0 -1 -1 834
0 -1 1 833
0 0 0 874
0 0 0 875
0 0 0 876
0 1 -1 860
0 1 1 859
1 -1 0 829
1 0 -1 872
1 0 1 874
1 1 0 856 ];
%
[~,~,X] = cellfun(@unique,num2cell(M(:,1:end-1),1),'Uni',0);
N = cellfun(@(s)accumarray(s,M(:,end),[],@mean),X, 'Uni',0);
out = [N{:}]
creates this output matrix, where the rows correspond to [-1;0;1]:
>> out
out =
865 833.25 861.5
858.71 875.71 858.71
857.75 859.75 861.25

更多回答(2 个)

Star Strider
Star Strider 2016-3-18
I would use three concatenated accumarray calls:
M = [-1 -1 0 837
-1 0 -1 880
-1 0 1 879
-1 1 0 864
0 -1 -1 834
0 -1 1 833
0 0 0 874
0 0 0 875
0 0 0 876
0 1 -1 860
0 1 1 859
1 -1 0 829
1 0 -1 872
1 0 1 874
1 1 0 856];
Result = [accumarray(M(:,1)+2, M(:,4), [], @mean), accumarray(M(:,2)+2, M(:,4), [], @mean), accumarray(M(:,3)+2, M(:,4), [], @mean)];
Result =
865 833.25 861.5
858.71 875.71 858.71
857.75 859.75 861.25
Here, the columns correspond to those in ‘M(:,1:3)’ and the rows correspond to ‘[-1; 0; 1]’ respectively.

Image Analyst
Image Analyst 2016-3-18
If you have the Statistics and Machine Learning Toolbox, you can use grpstats(), but I don't know if it would be any more compact that what you're already doing.

类别

Help CenterFile Exchange 中查找有关 Creating and Concatenating Matrices 的更多信息

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by