5
$\begingroup$

I have the following list consisting of a specified number of $(x,y)$ coordinates. Now I want to add the values of $y$ for which the $x$ values are same. For e.g. I want to convert the list $\{\{2,5\},\{2,7\},\{2,9\},\{3,1\},\{3,5\},\{4,2\}\}$ to $\{\{2,21\},\{3,6\},\{4,2\}\}$. Any guidance on how to go about this would be appreciated.

data = {{34, 1.35525*10^-20}, {35, 0}, {36, 8.94467*10^-19}, {37, 0}, 
{38,2.90702*10^-17}, {39, 0}, {40, 6.20164*10^-16}, {41, 0}, {42, 
9.76758*10^-15}, {43, 0}, {44, 1.21118*10^-13}, {45, 0}, 
{46,1.23137*10^-12}, {47, 0}, {48, 1.05546*10^-11}, {49, 0}, {0, 
7.78399*10^-11}, {1, 0}, {2, 5.01635*10^-10}, {3, 0}, {4, 
2.85932*10^-9}, {5, 0}, {6, 1.45565*10^-8}, {7, 0}, {8, 6.67175*10^-8}, 
{9,0}, {10, 2.77134*10^-7}, {11, 0}, {12, 1.04915*10^-6}, {13, 0}, 
{14,3.63705*10^-6}, {15, 0}, {16, 0.0000115931}, {17, 0}, {18, 
0.0000340974}, {19, 0}, {20, 0.0000928207}, {21, 0}, {22, 0.000234494}, {23, 
0}, {24, 0.000551062}, {25, 0}, {26, 0.00120709}, {27, 0}, {28, 0.00246904}, 
{29, 0}, {30, 0.00472339}, {31, 0}, {32, 0.00846273}, {33, 0}, {34, 
0.0142174}, {35, 0}, {36, 0.0224197}, {37, 0}, {38, 0.0332144}, {39, 0},{40, 
0.0462629}, {41, 0}, {42, 0.0606204}, {43, 0}, {44, 0.0747652}, {45, 0}, 
{46, 0.0868241}, {47, 0}, {48, 0.0949638}, {49, 0}, {0, 0.0978415}, {1, 
0}, {2, 0.0949638}, {3, 0}, {4, 0.0868241}, {5, 0}, {6, 0.0747652}, {7, 0}, 
{8, 0.0606204}, {9, 0}, {10, 0.0462629}, {11, 0}, {12, 0.0332144}, {13, 0}, 
{14, 0.0224197}, {15, 0}, {16, 0.0142174}, {17, 0}, {18, 0.00846273}, {19, 
0}, {20, 0.00472339}, {21, 0}, {22, 0.00246904}, {23, 0}, {24, 0.00120709}, 
{25, 0}, {26, 0.000551062}, {27, 0}, {28, 0.000234494}, {29, 0}, {30, 
0.0000928207}, {31, 0}, {32, 0.0000340974}, {33, 0}, {34, 0.0000115931}, 
{35, 0}, {36, 3.63705*10^-6}, {37, 0}, {38, 1.04915*10^-6}, {39, 0}, {40, 
2.77134*10^-7}, {41, 0}, {42, 6.67175*10^-8}, {43, 0}, {44, 1.45565*10^-8}, 
{45, 0}, {46, 2.85932*10^-9}, {47, 0}, {48, 5.01635*10^-10}, {49, 0}, {0, 
7.78399*10^-11}, {1, 0}, {2, 1.05546*10^-11}, {3, 0}, {4, 1.23137*10^-12}, 
{5, 0}, {6, 1.21118*10^-13}, {7, 0}, {8, 9.76758*10^-15}, {9, 0}, {10, 
6.20164*10^-16}, {11, 0}, {12, 2.90702*10^-17}, {13, 0}, {14, 
8.94467*10^-19}, {15, 0}, {16, 1.35525*10^-20}}
$\endgroup$

4 Answers 4

3
$\begingroup$

Try this:

KeySort[GroupBy[data, First -> Last, Total]]
list = Values[assoc]

<|0 -> 0.0978415, 1 -> 0, 2 -> 0.0949638, 3 -> 0, 4 -> 0.0868241, 5 -> 0, 6 -> 0.0747652, 7 -> 0, 8 -> 0.0606205, 9 -> 0, 10 -> 0.0462632, 11 -> 0, 12 -> 0.0332154, 13 -> 0, 14 -> 0.0224233, 15 -> 0, 16 -> 0.014229, 17 -> 0, 18 -> 0.00849683, 19 -> 0, 20 -> 0.00481621, 21 -> 0, 22 -> 0.00270353, 23 -> 0, 24 -> 0.00175815, 25 -> 0, 26 -> 0.00175815, 27 -> 0, 28 -> 0.00270353, 29 -> 0, 30 -> 0.00481621, 31 -> 0, 32 -> 0.00849683, 33 -> 0, 34 -> 0.014229, 35 -> 0, 36 -> 0.0224233, 37 -> 0, 38 -> 0.0332154, 39 -> 0, 40 -> 0.0462632, 41 -> 0, 42 -> 0.0606205, 43 -> 0, 44 -> 0.0747652, 45 -> 0, 46 -> 0.0868241, 47 -> 0, 48 -> 0.0949638, 49 -> 0|>

{0.0978415, 0, 0.0949638, 0, 0.0868241, 0, 0.0747652, 0, 0.0606205, 0, 0.0462632, 0, 0.0332154, 0, 0.0224233, 0, 0.014229, 0, 0.00849683, 0, 0.00481621, 0, 0.00270353, 0, 0.00175815, 0, 0.00175815, 0, 0.00270353, 0, 0.00481621, 0, 0.00849683, 0, 0.014229, 0, 0.0224233, 0, 0.0332154, 0, 0.0462632, 0, 0.0606205, 0, 0.0747652, 0, 0.0868241, 0, 0.0949638, 0}

I also provide a method that employs SparseArray with additive assembly. This should be faster for very long datasets.

list = With[{spopt = SystemOptions["SparseArrayOptions"]},
 Internal`WithLocalSettings[
  SetSystemOptions["SparseArrayOptions" -> {"TreatRepeatedEntries" -> Total}],

  Normal[SparseArray[Partition[data[[All, 1]], 1] + 1 -> data[[All, 2]]]],

  SetSystemOptions[spopt]]
 ]
$\endgroup$
2
$\begingroup$

Another method

{#[[1, 1]], Total@#[[;; , 2]]} & /@ GatherBy[data, First] // Sort

{{0, 0.0978415}, {1, 0}, {2, 0.0949638}, {3, 0}, {4, 0.0868241}, {5, 0}, {6, 0.0747652}, {7, 0}, {8, 0.0606205}, {9, 0}, {10, 0.0462632}, {11, 0}, {12, 0.0332154}, {13, 0}, {14, 0.0224233}, {15, 0}, {16, 0.014229}, {17, 0}, {18, 0.00849683}, {19, 0}, {20, 0.00481621}, {21, 0}, {22, 0.00270353}, {23, 0}, {24, 0.00175815}, {25, 0}, {26, 0.00175815}, {27, 0}, {28, 0.00270353}, {29, 0}, {30, 0.00481621}, {31, 0}, {32, 0.00849683}, {33, 0}, {34, 0.014229}, {35, 0}, {36, 0.0224233}, {37, 0}, {38, 0.0332154}, {39, 0}, {40, 0.0462632}, {41, 0}, {42, 0.0606205}, {43, 0}, {44, 0.0747652}, {45, 0}, {46, 0.0868241}, {47, 0}, {48, 0.0949638}, {49, 0}}

$\endgroup$
1
$\begingroup$

One way to approach this is to select all the terms with identical first elements, and add the second elements together:

tl = Union[Transpose[data][[1]]]; 
Table[{i, Total[Transpose[Select[data, #[[1]] == i &]][[2]]]}, {i, tl}]

For the simple case:

data = {{2, 5}, {2, 7}, {2, 9}, {3, 1}, {3, 5}, {4, 2}};

this gives

{{2, 21}, {3, 6}, {4, 2}}
$\endgroup$
1
$\begingroup$

We can use SplitBy

{#[[1, 1]], Total@#[[All, 2]]} & /@ SplitBy[Sort@data, First]

{{0, 0.0978415}, {1, 0}, {2, 0.0949638}, {3, 0}, {4, 0.0868241}, {5, 0}, {6, 0.0747652}, {7, 0}, {8, 0.0606205}, {9, 0}, {10, 0.0462632}, {11, 0}, {12, 0.0332154}, {13, 0}, {14, 0.0224233}, {15, 0}, {16, 0.014229}, {17, 0}, {18, 0.00849683}, {19, 0}, {20, 0.00481621}, {21, 0}, {22, 0.00270353}, {23, 0}, {24, 0.00175815}, {25, 0}, {26, 0.00175815}, {27, 0}, {28, 0.00270353}, {29, 0}, {30, 0.00481621}, {31, 0}, {32, 0.00849683}, {33, 0}, {34, 0.014229}, {35, 0}, {36, 0.0224233}, {37, 0}, {38, 0.0332154}, {39, 0}, {40, 0.0462632}, {41, 0}, {42, 0.0606205}, {43, 0}, {44, 0.0747652}, {45, 0}, {46, 0.0868241}, {47, 0}, {48, 0.0949638}, {49, 0}}

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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