2
$\begingroup$

Is there any equivalent of MATLAB's accumarray?

I'm looking for an equivalent of:

accumarray(A(:),B(:),[],@mean)

where A and B are two matrix datasets.

EDIT: As asked in the comment, I will provide a bit more from the MATLAB code. As far as I understood, the first matrix contains a set of radius values (all integer values), the second contains a random pattern (here 0's and 1's) like this:

(* A(:) *)
a = Table[Round@Sqrt[x^2 + y^2], {y, -5, 5, 1.}, {x, -5, 5, 1}];
(* B(:) *)
SeedRandom[1238];
b = Table[x y, {y, RandomInteger[1, 5]}, {x, RandomInteger[1, 5]}] 

Now accumarray(A(:),B(:),[],@mean) seems to virtually collect all matrix elements of $b$ where the elements $a_{ij}$ share the same value and than the function @mean is applied to all those virtually collected values. After this the obtained values are written in a List containing {Value of a, mean of all values of b}. I think this is what the code is supposed to do.

$\endgroup$
  • $\begingroup$ Any $n \times m$ Matrix, Input as well as output. $\endgroup$ – Kay Aug 17 '17 at 12:44
  • 2
    $\begingroup$ @Kay This site is about Mathematica, information not related to it should be included or linked, that is quite obvious. Unless we talk about common knowledge, but the definition of accumarray does not seem to be part of it. $\endgroup$ – Kuba Aug 17 '17 at 13:00
  • 1
    $\begingroup$ @Kuba Thanks for your hint! I'll try to respect that for the next time! $\endgroup$ – Kay Aug 17 '17 at 13:04
  • 1
    $\begingroup$ I'm not sure I understand. All you need to do is explain what you want to do in plain English, and not rely on a piece of MATLAB. The question should be understandable even if that MATLAB code is removed. Or are you saying that you do not fully understand what accumarray(A(:),B(:),[],@mean) does? $\endgroup$ – Szabolcs Aug 17 '17 at 13:20
  • 2
    $\begingroup$ @Kay actually, I doubt that MORE matlab code would help. I was hoping you could show us a simple example of the inputs you would give to this function in Mathematica notation, and the output you desire, also in Mathematica notation, together with a description in English of the operation you want to carry out. If you don't understand what that piece of code does, you might go ask about that on a MATLAB forum first. $\endgroup$ – MarcoB Aug 17 '17 at 13:26
5
$\begingroup$
 SeedRandom[1238];
 n = 10;
 m = 100;
 f = Mean;
 a = RandomInteger[{1, n}, {m, 2}];
 b = RandomInteger[{0, 1}, {m}];

The first application of accumarray that came to my mind is the assembly of SparseArrays. This can be directly done with

sparseresult = With[{spopt = SystemOptions["SparseArrayOptions"]},
  Internal`WithLocalSettings[
   SetSystemOptions["SparseArrayOptions" -> {"TreatRepeatedEntries" -> f@*List}],
   SparseArray[a -> b],
   SetSystemOptions[spopt]]
  ];
sparseresult["NonzeroValues"]

A more flexible (but not as efficient way) to do it is by using GrouBy as follows

groupbyresult = Map[
  f,
  GroupBy[Transpose[{a, b}], First -> Last]
  ]

An alternative way can be obtained with Merge

mergeresult = Merge[
  Association /@ Thread[Rule[a, b]],
  f
  ]

Note that the ordering of the resulting array is not uniquely defined. Hence, using Associations is a robust way to represent it.

$\endgroup$
  • $\begingroup$ What is the purpose of Flatten@b in groupbyresult? b already has a flattened form?! $\endgroup$ – Kay Aug 17 '17 at 15:03
  • 1
    $\begingroup$ None. I removed it. $\endgroup$ – Henrik Schumacher Aug 17 '17 at 15:06
  • 2
    $\begingroup$ For safety, one might consider using Internal`WithLocalSettings[] (see e.g. this) when playing around with SetSystemOptions[]. $\endgroup$ – J. M. will be back soon Aug 17 '17 at 15:39
  • $\begingroup$ @J.M.: Thanks for the hint! I have incorporated it into the answer and also into my own utility package. $\endgroup$ – Henrik Schumacher Aug 18 '17 at 1:41
  • $\begingroup$ Probably the only thing I would have done differently would be to put in sparseresult = SparseArray[a -> b]; sparseresult["NonzeroValues"] (or even SparseArray[a -> b] @ "NonzeroValues" if you like things terse) as the second argument to Internal`WithLocalSettings[]; as mentioned in the answer I linked to, whatever is in the second argument is automatically returned. But, your way works too. $\endgroup$ – J. M. will be back soon Aug 18 '17 at 9:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.