2
$\begingroup$

I have a long list of events consisting of pairs

     {{e_1,w_1},{e_2,w_2}, ....{e_n,w_n}}

I want to bin the energies e_i and then sum the 'weights' w_i of all events in a particular bin of energy e. The w_i are not true weights, because some of them can be negative. Thus I cannot use WeightedData. What is an efficient way to achieve this binning with 'weight' summation in each bin?

Here is some example data:

em = {1, 1.5, 3., 4., 2.1, 7.3, 6., 8.5, 9.9, 5.7}
w = {10, 5, 3, 2, 5, 10, 20, 5, -7, 8}

The bins are 0-5 and 5-10, and the result should be {25, 36}.

$\endgroup$
6
  • 2
    $\begingroup$ GroupBy based on a Rounded e value? $\endgroup$ – Szabolcs Jun 22 '18 at 19:06
  • 1
    $\begingroup$ Total[Map[#[[1]]#[[2]]&, {{e_1,w_1},{e_2,w_2}, ....{e_n,w_n}}]? $\endgroup$ – Ulrich Neumann Jun 22 '18 at 19:23
  • 2
    $\begingroup$ Example data would be great. $\endgroup$ – Henrik Schumacher Jun 22 '18 at 19:57
  • $\begingroup$ So, here is an example: em = {1, 1.5, 3., 4., 2.1, 7.3, 6., 8.5, 9.9, 5.7} w = {10, 5, 3, 2, 5, 10, 20, 5, -7, 8} Now we bin this into two em-bins 0-5 and 5- 10. in each of these bins I need the sum of the weights of the energies in that bin. The result should then be: {25,43} $\endgroup$ – user3584513 Jun 24 '18 at 14:35
  • $\begingroup$ sorry, correction: the result should be {25,36} $\endgroup$ – user3584513 Jun 24 '18 at 14:43
2
$\begingroup$

Another option is to use Nearest (using M10.3+):

Total[
    Nearest[em -> w, {2.5, 7.5}, {Infinity, 2.5}],
    {2}
]

{25, 36}

$\endgroup$
1
  • $\begingroup$ Curiously this code crashes Mathematica 10.1. $\endgroup$ – Mr.Wizard Jun 26 '18 at 14:03
4
$\begingroup$

GroupBy

em = {1, 1.5, 3., 4., 2.1, 7.3, 6., 8.5, 9.9, 5.7};
w = {10, 5, 3, 2, 5, 10, 20, 5, -7, 8} ;
emw = Transpose[{em, w}];

Values @ GroupBy[emw, Quotient[First@#, 5] &, Total]  

{{11.6, 25}, {37.4, 36}}

To get just the weight totals

Values @ GroupBy[emw, Quotient[First@#, 5]&->Last , Total] 

{25, 36}

BinLists

It is more convenient to specify bins with BinLists

Total[Join @@@ BinLists[emw, 5, Abs[Subtract @@ MinMax @ w]],{2}]

{{11.6, 25}, {37.4, 36}}

$\endgroup$
1
  • $\begingroup$ Using 10^7 pairs, your first version takes about 0.5 s on my machine (M12), the second about 0.7 s, and the last is much slower at 3.3 s. $\endgroup$ – Martin Rommel Oct 28 '19 at 13:34

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.