average of range of values in a matrix

5 views (last 30 days)
Fabi Boro
Fabi Boro on 13 Nov 2015
Answered: Andrei Bobrov on 18 Apr 2016
Hello,
I have a matrix d (NxN), which looks like that:
Can I use a for loop to say, calculate the average value of all lines in column 1, which have the same value in column 3?
n = amount of same values (here 3 x 11)
and give me a vektor which looks like that:
Can I tell the for loop to find automatically all multiple values in column 3? Like now it's 11, 16, 21, but maybe the next matrix has in column 3 10, 12, 14,...

Answers (3)

dpb
dpb on 13 Nov 2015
Edited: dpb on 13 Nov 2015
[u,~,ib]=unique(x(:,3)); % get the unique values and locations for each
val=x(:,1:2); % shorthand for the subset over which to average
mx(:,3)=u; % preallocate for the result array & assign index values
for i=1:2 % for the two columns
mx(:,i)=accumarray(ib,val(:,i),[],@mean); % compute the mean over the subsets
end
Seems like should be able to do it w/o the loop over the columns but I drew a blank at the moment as to how to since accumarray val argument must be a vector
  2 Comments
Image Analyst
Image Analyst on 13 Nov 2015
Yeah, I thought of accumarray too, but accumarray is such a mind-bender I have to research it in the help every time because it's kind of complicated, so sometimes I just do the brute force but intuitive approach. However, I'm sure Andrei Bobrov, master of the one-liners, will come along shortly and do the whole thing in one compact but totally cryptic and impenetrable line of code.
dpb
dpb on 13 Nov 2015
Yeah, Andrei's the guru there, fur shur... :) I agree w/ accumarray; it's capable but complex-enough to always take a couple of tries and if it's been a while since last foray.
I realize I forgot to add the OP's last wish above; namely to include the value of the indexing variable as the last column...
Could change a little; start with
mx(:,3)=u;
for the preallocation and setting the values together...

Sign in to comment.


Fabi Boro
Fabi Boro on 14 Nov 2015
thank you very much fot the detailed and fast reply.
I'm afraid I'm a beginner in Matlab and I'm trying to understand your code but I don't get it entirely. "mx" stands for my Matrix, but I get an error message for the line
[u,~,ib]=unique(x(:,3));
"Reference to a cleared variable x." what is the difference bewteen your first suggestion and your second to start with
mx(:,3)=u;
?
  1 Comment
dpb
dpb on 14 Nov 2015
x is a placeholder for your original variable--you don't say what you've named the...well, in looking again I see that I did overlook that in, sorry--use 'd' in place of 'x'.
mx stands for "mean of x" for the result; use whatever you want instead, of course.
The difference between the two solutions is that the first leaves you with a 2-column result of the two means; the latter finishes the job by storing the unique indices vector of the groups as the third column per the original request. Matlab automagically allocates full memory to the largest subscript dimension in an assignment of this kind; try, say,
newvar(3,3)=pi
at the command line to see how the assignment to a single location serves the same function as
newvar=zeros(3);
newvar(3,3)=pi;
it simply saves a step.

Sign in to comment.


Andrei Bobrov
Andrei Bobrov on 18 Apr 2016
Hi friends! In four rows
A = [1234 785 11
5678 457 11
9101 390 11
2467 381 16
3573 737 16
2354 938 16
8467 729 21
3477 900 21];
[a,~,c] = unique(A(:,3));
[x,y] = ndgrid(c,1:2);
A1 = A(:,1:2);
out = [accumarray([x(:),y(:)],A1(:),[],@mean),a];

Community Treasure Hunt

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

Start Hunting!