필터 지우기
필터 지우기

Can I get rid of this for loop?

조회 수: 1 (최근 30일)
Ryan
Ryan 2016년 3월 18일
편집: Stephen23 2016년 3월 18일
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