1
$\begingroup$

For the following let me use this notation:

$\qquad \text{data}=\{\{x_1,y_{11}\}, \{x_1,y_{12}\},\{x_1,y_{1N}\},\,\dots,\,\{x_2,y_{21}\}, \{x_2,y_{22}\},\{x_2,x_{2M}\},\,\dots\}$,

where $M\neq N$. What I'm trying to find are the smallest values, $\{\{x_1,y_{11}\}, \{x_2,y_{21}\},\dots\}$, and the largest values, $\{\{x_1,y_{1N}\}, \{x_2,y_{2M}\},\,\dots\}$

As an example, expressed in the Wolfram Language:

data = 
 {{0.2,0.255556}, {0.2,0.411111}, {0.2,0.566667}, {0.2,0.722222}, {0.2,0.877778}, {0.2,1.03333}, {0.2,1.18889}, {0.2,1.34444}, {0.2,1.5},
  {0.4,0.411111}, {0.4,0.566667}, {0.4,0.722222}, {0.4,0.877778}, {0.4,1.03333}, {0.4,1.18889}, {0.4,1.34444}, {0.4,1.5},
  {0.6,0.566667}, {0.6,0.722222}, {0.6,0.877778}, {0.6,1.03333}, {0.6,1.18889}, {0.6,1.34444}, {0.6,1.5}, 
  {0.8,0.722222}, {0.8,0.877778}, {0.8,1.03333}, {0.8,1.18889}, {0.8,1.34444}, {0.8,1.5}, 
  {1.,1.03333}, {1.,1.18889}, {1.,1.34444}, {1.,1.5},{1.2,1.18889}, {1.2,1.34444}, {1.2,1.5}, {1.4,1.5}}

SmallestValues = 
  {{0.2, 0.255556}, {0.4, 0.411111}, {0.6, 0.566667}, {0.8, 0.722222}, {1., 1.03333}, {1.2, 1.18889}, {1.4, 1.5}}
BiggestValues = 
  {{0.2, 1.5}, {0.4, 1.5}, {0.6, 1.5}, {0.8, 1.5}, {1., 1.5}, {1.2, 1.5}, {1.4, 1.5}}

My problem is that I honestly can't think of a way to get this done in Mathematica. I'm used to python coding and there I would probably change the type from a list to something like a matrix and then manipulate this using for-loops, but this seems rather inefficient and is presumably not necessary here.

$\endgroup$
  • $\begingroup$ Do you mean "from" instead of "form"? $\endgroup$ – user64494 May 3 at 18:52
5
$\begingroup$
Join @@ Values @ GroupBy[data, First, MinimalBy[Last]]

{{0.2, 0.255556}, {0.4, 0.411111}, {0.6, 0.566667}, {0.8,   0.722222}, {1., 1.03333}, {1.2, 1.18889}, {1.4, 1.5}}

Join @@ Values @ GroupBy[data, First, MaximalBy[Last]]

{{0.2, 1.5}, {0.4, 1.5}, {0.6, 1.5}, {0.8, 1.5}, {1., 1.5}, {1.2,   1.5}, {1.4, 1.5}}

$\endgroup$
3
$\begingroup$

If your data is guaranteed to be ordered consecutively for the same $x$, then:

groups = SplitBy[data, #[[1]] &];
SmallestValues = groups[[All, 1]];
BiggestValues = groups[[All, -1]];

If not, you can look into GroupBy function and the code will be similar.

$\endgroup$
3
$\begingroup$

You may compose a few functions together to collect your results. There are a few ways to compose the functions.

With Query and RightComposition

{smallest, biggest} = 
 Query[GroupBy[First -> Last] /* KeyValueMap[Thread[{##}] &] /* Transpose, MinMax]@data

With Map and Prefix.

{smallest, biggest} = 
 Transpose@KeyValueMap[Thread[{##}] &, MinMax /@ GroupBy[First -> Last]@data]

Both give

{
 {{0.2,0.255556},{0.4,0.411111},{0.6,0.566667},{0.8,0.722222},{1.,1.03333},{1.2,1.18889},{1.4,1.5}},
 {{0.2,1.5},{0.4,1.5},{0.6,1.5},{0.8,1.5},{1.,1.5},{1.2,1.5},{1.4,1.5}}
}

Hope this helps.

$\endgroup$
3
$\begingroup$
KeyValueMap[List]@GroupBy[data, First -> Last, Min]

{{0.2, 0.255556}, {0.4, 0.411111}, {0.6, 0.566667}, {0.8, 0.722222}, {1., 1.03333}, {1.2, 1.18889}, {1.4, 1.5}}

KeyValueMap[List]@GroupBy[data, First -> Last, Max]

{{0.2, 1.5}, {0.4, 1.5}, {0.6, 1.5}, {0.8, 1.5}, {1., 1.5}, {1.2, 1.5}, {1.4, 1.5}}

Both at once:

KeyValueMap[List]@GroupBy[data, First -> Last, MinMax]

{{0.2, {0.255556, 1.5}}, {0.4, {0.411111, 1.5}}, {0.6, {0.566667, 1.5}}, {0.8, {0.722222, 1.5}}, {1., {1.03333, 1.5}}, {1.2, {1.18889, 1.5}}, {1.4, {1.5, 1.5}}}

You can leave out the KeyValueMap[List]@ part and only use the GroupBy part if you want to have an association instead of a list.

$\endgroup$
2
$\begingroup$

This works even if the data are out of order:

g = Gather[Sort[data], #1[[1]] == #2[[1]] &];

Map[Sort, g][[All, 1]]

{{0.2, 0.255556}, {0.4, 0.411111}, {0.6, 0.566667}, {0.8, 0.722222}, {1., 1.03333}, {1.2, 1.18889}, {1.4, 1.5}}

Map[Sort, g][[All, -1]]

{{0.2, 1.5}, {0.4, 1.5}, {0.6, 1.5}, {0.8, 1.5}, {1., 1.5}, {1.2, 1.5}, {1.4, 1.5}}

$\endgroup$

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.