Path: news.mathworks.com!not-for-mail
From: <HIDDEN>
Newsgroups: comp.soft-sys.matlab
Subject: Re: average if: average values in column if values in other colum are equal
Date: Fri, 15 Jul 2011 20:13:28 +0000 (UTC)
Organization: The MathWorks, Inc.
Lines: 41
Message-ID: <ivq718$k05$1@newscl01ah.mathworks.com>
References: <ivpqne$cbd$1@newscl01ah.mathworks.com>
Reply-To: <HIDDEN>
NNTP-Posting-Host: www-00-blr.mathworks.com
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit
X-Trace: newscl01ah.mathworks.com 1310760808 20485 172.30.248.45 (15 Jul 2011 20:13:28 GMT)
X-Complaints-To: news@mathworks.com
NNTP-Posting-Date: Fri, 15 Jul 2011 20:13:28 +0000 (UTC)
X-Newsreader: MATLAB Central Newsreader 1187260
Xref: news.mathworks.com comp.soft-sys.matlab:736442

"Daphne" <daphnew_too_nospam@yahoo.com> wrote in message <ivpqne$cbd$1@newscl01ah.mathworks.com>...
> 
> I would like to average values in column 2 of a matrix that correspond to equal (and unique) values in column 1, a simple example:
> 
> a= [1.0000    0.5000
>     1.0000    0.4500
>     1.0000    0.6000
>     2.0000    1.0000
>     2.0000    1.2000
>     3.0000    3.0000
>     3.0000    3.5000
>     3.0000    3.0000];
> 
> should become 
> 
> b = [1.0000    0.5167
>     2.0000    1.1000
>     3.0000    3.1667];
> 
> is there a non-loop way to do this, for matrices with >100k elements?...
> I have tried to do logicals in a loop, but these take too long (example of 126 sec on 8653 calls from the profiler). My try: 
> 
> unique_a = unique(a(:,1));
> b = NaN(size(unique_a,1),2);
> for unique_ind = 1:size(unique_a,1)
>   data2avg = a(a(:,1) == unique_a(unique_ind),2);
>   b(unique_ind,:) = [unique_a(unique_ind),mean(data2avg) ];
> end
> 
> Any ideas on how to improve on this or do this better?
> 
> Thanks,
> Daphne
- - - - - - - - -
  If elements of a(:,1) are not necessarily indices, do this:

 [u,~,n] = unique(a(:,1));
 sz = [size(u,1),1];
 b = [u,accumarray(n,a(:,2),sz)./accumarray(n,1,sz)];

Roger Stafford