<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: Under-appreciated accumarray</title>
	<atom:link href="http://blogs.mathworks.com/loren/2008/02/20/under-appreciated-accumarray/feed/" rel="self" type="application/rss+xml" />
	<link>http://blogs.mathworks.com/loren/2008/02/20/under-appreciated-accumarray/</link>
	<description>Loren Shure works on design of the MATLAB language at MathWorks. She writes here about once a week on MATLAB programming and related topics.</description>
	<lastBuildDate>Fri, 17 Feb 2012 13:41:33 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
	<item>
		<title>By: Par</title>
		<link>http://blogs.mathworks.com/loren/2008/02/20/under-appreciated-accumarray/#comment-32649</link>
		<dc:creator>Par</dc:creator>
		<pubDate>Mon, 14 Nov 2011 23:34:06 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.mathworks.com/loren/2008/02/20/under-appreciated-accumarray/#comment-32649</guid>
		<description>Got it Peter, completed the exercise :)   Your solution is quite elegant.  I am happy that I finally understood this function.  The fact that you can pass a function handle makes this function so powerful!</description>
		<content:encoded><![CDATA[<p>Got it Peter, completed the exercise :)   Your solution is quite elegant.  I am happy that I finally understood this function.  The fact that you can pass a function handle makes this function so powerful!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Peter Perkins</title>
		<link>http://blogs.mathworks.com/loren/2008/02/20/under-appreciated-accumarray/#comment-32642</link>
		<dc:creator>Peter Perkins</dc:creator>
		<pubDate>Mon, 14 Nov 2011 16:32:59 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.mathworks.com/loren/2008/02/20/under-appreciated-accumarray/#comment-32642</guid>
		<description>Par -

1) You should not depend on the internal implementation of accumarray. Stick to what the help tells you.

2) There are probably several ways to do what you&#039;re asking about, but here&#039;s the way I&#039;d approach it (I&#039;ll leave it as an exercise to figure out how this works):

&lt;pre&gt;
   [u,~,i] = unique(c(:,1));
   r = (1:size(c,1))&#039;;
   groups = accumarray(i,r,size(u),@(t) { c(t,2:4) });
&lt;/pre&gt;</description>
		<content:encoded><![CDATA[<p>Par -</p>
<p>1) You should not depend on the internal implementation of accumarray. Stick to what the help tells you.</p>
<p>2) There are probably several ways to do what you&#8217;re asking about, but here&#8217;s the way I&#8217;d approach it (I&#8217;ll leave it as an exercise to figure out how this works):</p>
<pre>
   [u,~,i] = unique(c(:,1));
   r = (1:size(c,1))';
   groups = accumarray(i,r,size(u),@(t) { c(t,2:4) });
</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Peter Perkins</title>
		<link>http://blogs.mathworks.com/loren/2008/02/20/under-appreciated-accumarray/#comment-32641</link>
		<dc:creator>Peter Perkins</dc:creator>
		<pubDate>Mon, 14 Nov 2011 16:20:43 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.mathworks.com/loren/2008/02/20/under-appreciated-accumarray/#comment-32641</guid>
		<description>Gursu, meanangle appears to be a submission to the MATLAB File Exchange.  I know nothing about it, but since accumarray accetps a function handle, I can only assume that you could pass accumarray a function handle to meanangle.</description>
		<content:encoded><![CDATA[<p>Gursu, meanangle appears to be a submission to the MATLAB File Exchange.  I know nothing about it, but since accumarray accetps a function handle, I can only assume that you could pass accumarray a function handle to meanangle.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: gursu</title>
		<link>http://blogs.mathworks.com/loren/2008/02/20/under-appreciated-accumarray/#comment-32637</link>
		<dc:creator>gursu</dc:creator>
		<pubDate>Sun, 13 Nov 2011 21:45:28 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.mathworks.com/loren/2008/02/20/under-appreciated-accumarray/#comment-32637</guid>
		<description>is it possible to implement @meanangle, or better, @nanmeanangle function to accumarray?</description>
		<content:encoded><![CDATA[<p>is it possible to implement @meanangle, or better, @nanmeanangle function to accumarray?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Par</title>
		<link>http://blogs.mathworks.com/loren/2008/02/20/under-appreciated-accumarray/#comment-32633</link>
		<dc:creator>Par</dc:creator>
		<pubDate>Sat, 12 Nov 2011 15:13:48 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.mathworks.com/loren/2008/02/20/under-appreciated-accumarray/#comment-32633</guid>
		<description>Hello Again Peter,

Continuing on my latest reply, I figure there are two ways to solve the problem. One is to first sort the original cell array based on its first column so that when I use &#039;unique&#039; to get the &#039;n&#039; vector, it will be sorted. Then, I can use 3 separate accumarray statements as follows:

&lt;pre&gt;
groups2 = accumarray(n,cell2mat(c1(:,2)),size(u),@(t) {t});
groups3 = accumarray(n,cell2mat(c1(:,3)),size(u),@(t) {t});
groups4 = accumarray(n,cell2mat(c1(:,4)),size(u),@(t) {t});
&lt;/pre&gt;

The other solution I can think of is to first get the list of unique strings using &#039;unique&#039; and then use a loop along with &#039;strcmpi&#039; to find the indices for all the occurrences of each unique string in the main cell array and accumulate the rows manually in separate cells or the fields of a structure.

Other than these two solutions, is there a better way?

Thanks a lot!</description>
		<content:encoded><![CDATA[<p>Hello Again Peter,</p>
<p>Continuing on my latest reply, I figure there are two ways to solve the problem. One is to first sort the original cell array based on its first column so that when I use &#8216;unique&#8217; to get the &#8216;n&#8217; vector, it will be sorted. Then, I can use 3 separate accumarray statements as follows:</p>
<pre>
groups2 = accumarray(n,cell2mat(c1(:,2)),size(u),@(t) {t});
groups3 = accumarray(n,cell2mat(c1(:,3)),size(u),@(t) {t});
groups4 = accumarray(n,cell2mat(c1(:,4)),size(u),@(t) {t});
</pre>
<p>The other solution I can think of is to first get the list of unique strings using &#8216;unique&#8217; and then use a loop along with &#8216;strcmpi&#8217; to find the indices for all the occurrences of each unique string in the main cell array and accumulate the rows manually in separate cells or the fields of a structure.</p>
<p>Other than these two solutions, is there a better way?</p>
<p>Thanks a lot!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Par</title>
		<link>http://blogs.mathworks.com/loren/2008/02/20/under-appreciated-accumarray/#comment-32628</link>
		<dc:creator>Par</dc:creator>
		<pubDate>Fri, 11 Nov 2011 23:16:08 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.mathworks.com/loren/2008/02/20/under-appreciated-accumarray/#comment-32628</guid>
		<description>Sorry Peter.  I completely overlooked another requirement in my problem description earlier.  Actually, I have two more columns in the array &#039;c&#039;, for example, &#039;c&#039; looks like this:

&lt;pre&gt;

c = 
    &#039;ccc&#039;    [16]    [71]    &#039;n&#039;
    &#039;ccc&#039;    [98]    [ 4]    &#039;p&#039;
    &#039;a&#039;      [96]    [28]    &#039;n&#039;
    &#039;ccc&#039;    [49]    [ 5]    &#039;n&#039;
    &#039;bb&#039;     [81]    [10]    &#039;n&#039;
    &#039;a&#039;      [15]    [83]    &#039;n&#039;
    &#039;a&#039;      [43]    [70]    &#039;n&#039;
    &#039;bb&#039;     [92]    [32]    &#039;p&#039;
    &#039;ccc&#039;    [80]    [96]    &#039;p&#039;
    &#039;ccc&#039;    [96]    [ 4]    &#039;p&#039;

&lt;/pre&gt;

When I put the grouped elements in their respective bins, the corresponding elements in columns 3 and 4 also need to go into the bins in the same rows as the elements of col 2.  Is this possible?

Thank you.</description>
		<content:encoded><![CDATA[<p>Sorry Peter.  I completely overlooked another requirement in my problem description earlier.  Actually, I have two more columns in the array &#8216;c&#8217;, for example, &#8216;c&#8217; looks like this:</p>
<pre>

c =
    'ccc'    [16]    [71]    'n'
    'ccc'    [98]    [ 4]    'p'
    'a'      [96]    [28]    'n'
    'ccc'    [49]    [ 5]    'n'
    'bb'     [81]    [10]    'n'
    'a'      [15]    [83]    'n'
    'a'      [43]    [70]    'n'
    'bb'     [92]    [32]    'p'
    'ccc'    [80]    [96]    'p'
    'ccc'    [96]    [ 4]    'p'
</pre>
<p>When I put the grouped elements in their respective bins, the corresponding elements in columns 3 and 4 also need to go into the bins in the same rows as the elements of col 2.  Is this possible?</p>
<p>Thank you.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Par</title>
		<link>http://blogs.mathworks.com/loren/2008/02/20/under-appreciated-accumarray/#comment-32627</link>
		<dc:creator>Par</dc:creator>
		<pubDate>Fri, 11 Nov 2011 22:14:19 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.mathworks.com/loren/2008/02/20/under-appreciated-accumarray/#comment-32627</guid>
		<description>Got it!  Now I understand the utility of this function much more clearly.  Thank you so much for your explanations.  

About the unpredictable order of the resulting subset elements, I wonder then, the inner working of accumarray is not as simple as scanning the input array element by element and dropping each element into its appropriate bin as the code moves forward.  I am guessing that would have been quite inefficient?</description>
		<content:encoded><![CDATA[<p>Got it!  Now I understand the utility of this function much more clearly.  Thank you so much for your explanations.  </p>
<p>About the unpredictable order of the resulting subset elements, I wonder then, the inner working of accumarray is not as simple as scanning the input array element by element and dropping each element into its appropriate bin as the code moves forward.  I am guessing that would have been quite inefficient?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Peter Perkins</title>
		<link>http://blogs.mathworks.com/loren/2008/02/20/under-appreciated-accumarray/#comment-32626</link>
		<dc:creator>Peter Perkins</dc:creator>
		<pubDate>Fri, 11 Nov 2011 18:28:21 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.mathworks.com/loren/2008/02/20/under-appreciated-accumarray/#comment-32626</guid>
		<description>Par, the help for ACCUMARRAY says, &quot;Note: If the subscripts in SUBS are not sorted, FUN should not depend on the order of the values in its input data.&quot;  What that means is what you observed:  for FUN == @(t) {t}, the order of the elements in the output is not predictable.  HOWEVER, if the subscripts _are_ sorted, then the order of the elements will be what you expect.  So, if the order of the elements in the output is critical, you can always sort SUBS, and reorder VAL in parallel to that using the second output from SORT.

The following demonstrates that using ISSORTED is a win, at least for large arrays:

&gt;&gt; x = randn(10000000,1);
&gt;&gt; xs = sort(x);
&gt;&gt; 
&gt;&gt; tic, y = sort(x); toc
Elapsed time is 0.429657 seconds.
&gt;&gt; tic, y = sort(xs); toc
Elapsed time is 0.112595 seconds.
&gt;&gt; tic, if ~issorted(x), y = sort(x); end, toc
Elapsed time is 0.420848 seconds.
&gt;&gt; tic, if ~issorted(xs), y = sort(xs); end, toc
Elapsed time is 0.021241 seconds.</description>
		<content:encoded><![CDATA[<p>Par, the help for ACCUMARRAY says, &#8220;Note: If the subscripts in SUBS are not sorted, FUN should not depend on the order of the values in its input data.&#8221;  What that means is what you observed:  for FUN == @(t) {t}, the order of the elements in the output is not predictable.  HOWEVER, if the subscripts _are_ sorted, then the order of the elements will be what you expect.  So, if the order of the elements in the output is critical, you can always sort SUBS, and reorder VAL in parallel to that using the second output from SORT.</p>
<p>The following demonstrates that using ISSORTED is a win, at least for large arrays:</p>
<p>&gt;&gt; x = randn(10000000,1);<br />
&gt;&gt; xs = sort(x);<br />
&gt;&gt;<br />
&gt;&gt; tic, y = sort(x); toc<br />
Elapsed time is 0.429657 seconds.<br />
&gt;&gt; tic, y = sort(xs); toc<br />
Elapsed time is 0.112595 seconds.<br />
&gt;&gt; tic, if ~issorted(x), y = sort(x); end, toc<br />
Elapsed time is 0.420848 seconds.<br />
&gt;&gt; tic, if ~issorted(xs), y = sort(xs); end, toc<br />
Elapsed time is 0.021241 seconds.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Par</title>
		<link>http://blogs.mathworks.com/loren/2008/02/20/under-appreciated-accumarray/#comment-32625</link>
		<dc:creator>Par</dc:creator>
		<pubDate>Fri, 11 Nov 2011 16:08:05 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.mathworks.com/loren/2008/02/20/under-appreciated-accumarray/#comment-32625</guid>
		<description>Thanks a lot, Peter.  That really helps!  Your example is also a great aid to understand how this works.  Appreciate your help.

Just one more question: The elements in the subsets, i.e., in the &quot;groups&quot; cell array, do not seem to be in any particular order.  I thought they might be sorted in some order, either in ascending/descending, or in the order of occurrence in the &quot;c&quot; array.  But they seem to be randomly ordered.  Is that so?  Could you please throw some light on this?  Of course, it is no big deal to use the sort command to sort them, but if I know they are already sorted, then I wouldn&#039;t bother about sorting as the data I am dealing with is quite large, about 10-15 million elements. 

By the way, another quick question:  If we are unsure about the sort status of an array, then I know we can use the &#039;issorted&#039; command to check.  Now if the array happens to be already sorted, then does the redundant checking cost any computation time?  Even if the array is very large?

Thanks!</description>
		<content:encoded><![CDATA[<p>Thanks a lot, Peter.  That really helps!  Your example is also a great aid to understand how this works.  Appreciate your help.</p>
<p>Just one more question: The elements in the subsets, i.e., in the &#8220;groups&#8221; cell array, do not seem to be in any particular order.  I thought they might be sorted in some order, either in ascending/descending, or in the order of occurrence in the &#8220;c&#8221; array.  But they seem to be randomly ordered.  Is that so?  Could you please throw some light on this?  Of course, it is no big deal to use the sort command to sort them, but if I know they are already sorted, then I wouldn&#8217;t bother about sorting as the data I am dealing with is quite large, about 10-15 million elements. </p>
<p>By the way, another quick question:  If we are unsure about the sort status of an array, then I know we can use the &#8216;issorted&#8217; command to check.  Now if the array happens to be already sorted, then does the redundant checking cost any computation time?  Even if the array is very large?</p>
<p>Thanks!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Peter Perkins</title>
		<link>http://blogs.mathworks.com/loren/2008/02/20/under-appreciated-accumarray/#comment-32619</link>
		<dc:creator>Peter Perkins</dc:creator>
		<pubDate>Thu, 10 Nov 2011 13:43:30 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.mathworks.com/loren/2008/02/20/under-appreciated-accumarray/#comment-32619</guid>
		<description>Par, yes you can.  Your data are perhaps not in the most convenient form, but I&#039;ll say more in a moment.

First, set up some data like what you described.
&lt;pre&gt;
&gt;&gt; strs = {&#039;a&#039; &#039;bb&#039; &#039;ccc&#039;}&#039;;
&gt;&gt; s = strs(randi(3,10,1));
&gt;&gt; x = randn(10,1);
&gt;&gt; c =  [s num2cell(x)]
c = 
    &#039;bb&#039;     [ 0.74808]
    &#039;ccc&#039;    [-0.19242]
    &#039;ccc&#039;    [ 0.88861]
    &#039;ccc&#039;    [-0.76485]
    &#039;bb&#039;     [ -1.4023]
    &#039;a&#039;      [ -1.4224]
    &#039;a&#039;      [ 0.48819]
    &#039;a&#039;      [-0.17738]
    &#039;ccc&#039;    [-0.19605]
    &#039;a&#039;      [  1.4193]
&lt;/pre&gt;

Now pretend we don&#039;t know where c came from.

Create the group indices from the strings ...
&lt;pre&gt;
&gt;&gt; [u,~,i] = unique(c(:,1));
&lt;/pre&gt;

... and group the numeric data by the indices
&lt;pre&gt;
&gt;&gt; groups = accumarray(i,cell2mat(c(:,2)),size(u),@(t) {t});
&gt;&gt; groups{:}
ans =
      -1.4224
     -0.17738
      0.48819
       1.4193
ans =
      0.74808
      -1.4023
ans =
     -0.19242
     -0.19605
      0.88861
     -0.76485
&lt;/pre&gt;

Or compute grouped means
&lt;pre&gt;
&gt;&gt; groupMeans = accumarray(i,cell2mat(c(:,2)),size(u),@mean)
groupMeans =
     0.076938
      -0.3271
    -0.066178
&lt;/pre&gt;

Now, ACCUMARRAY requires the second input to be numeric, so in the above, you have to convert the second column of your cell array to a numeric column.  I imagine you have this one cell array because you wanted to mix string and numeric data in a single array.

If you have access to the Statistics Toolbox, you may find that using a dataset array instead of a cell array makes your life easier.  In fact, there&#039;s a function called GRPSTATS that will do both of the above for you.  You may also find that using a nominal (or ordinal) array for your string data, rather than a cell array makes your life easier too.  The dataset array would then contain one nominal and one numeric column.  For example:

&lt;pre&gt;
&gt;&gt; s = nominal(s);
&gt;&gt; d = dataset(s,x)
d = 
    s      x       
    bb      0.74808
    ccc    -0.19242
    ccc     0.88861
    ccc    -0.76485
    bb      -1.4023
    a       -1.4224
    a       0.48819
    a      -0.17738
    ccc    -0.19605
    a        1.4193
&gt;&gt; groupMeans = grpstats(d,&#039;s&#039;)
groupMeans = 
           s      GroupCount    mean_x   
    a      a      4              0.076938
    bb     bb     2               -0.3271
    ccc    ccc    4             -0.066178
&lt;/pre&gt;

Hope this helps.</description>
		<content:encoded><![CDATA[<p>Par, yes you can.  Your data are perhaps not in the most convenient form, but I&#8217;ll say more in a moment.</p>
<p>First, set up some data like what you described.</p>
<pre>
&gt;&gt; strs = {'a' 'bb' 'ccc'}';
&gt;&gt; s = strs(randi(3,10,1));
&gt;&gt; x = randn(10,1);
&gt;&gt; c =  [s num2cell(x)]
c =
    'bb'     [ 0.74808]
    'ccc'    [-0.19242]
    'ccc'    [ 0.88861]
    'ccc'    [-0.76485]
    'bb'     [ -1.4023]
    'a'      [ -1.4224]
    'a'      [ 0.48819]
    'a'      [-0.17738]
    'ccc'    [-0.19605]
    'a'      [  1.4193]
</pre>
<p>Now pretend we don&#8217;t know where c came from.</p>
<p>Create the group indices from the strings &#8230;</p>
<pre>
&gt;&gt; [u,~,i] = unique(c(:,1));
</pre>
<p>&#8230; and group the numeric data by the indices</p>
<pre>
&gt;&gt; groups = accumarray(i,cell2mat(c(:,2)),size(u),@(t) {t});
&gt;&gt; groups{:}
ans =
      -1.4224
     -0.17738
      0.48819
       1.4193
ans =
      0.74808
      -1.4023
ans =
     -0.19242
     -0.19605
      0.88861
     -0.76485
</pre>
<p>Or compute grouped means</p>
<pre>
&gt;&gt; groupMeans = accumarray(i,cell2mat(c(:,2)),size(u),@mean)
groupMeans =
     0.076938
      -0.3271
    -0.066178
</pre>
<p>Now, ACCUMARRAY requires the second input to be numeric, so in the above, you have to convert the second column of your cell array to a numeric column.  I imagine you have this one cell array because you wanted to mix string and numeric data in a single array.</p>
<p>If you have access to the Statistics Toolbox, you may find that using a dataset array instead of a cell array makes your life easier.  In fact, there&#8217;s a function called GRPSTATS that will do both of the above for you.  You may also find that using a nominal (or ordinal) array for your string data, rather than a cell array makes your life easier too.  The dataset array would then contain one nominal and one numeric column.  For example:</p>
<pre>
&gt;&gt; s = nominal(s);
&gt;&gt; d = dataset(s,x)
d =
    s      x
    bb      0.74808
    ccc    -0.19242
    ccc     0.88861
    ccc    -0.76485
    bb      -1.4023
    a       -1.4224
    a       0.48819
    a      -0.17738
    ccc    -0.19605
    a        1.4193
&gt;&gt; groupMeans = grpstats(d,'s')
groupMeans =
           s      GroupCount    mean_x
    a      a      4              0.076938
    bb     bb     2               -0.3271
    ccc    ccc    4             -0.066178
</pre>
<p>Hope this helps.</p>
]]></content:encoded>
	</item>
</channel>
</rss>

