3
$\begingroup$

There is a list in the form {a,b}, where the list is the numerical solution of some equation; List=Table[z[i]]. I need the "a" when "b" is minimal in the list.

$\endgroup$
2
  • $\begingroup$ What do you mean by minimal ? Can you give us a simple example with a list and what you want ? $\endgroup$
    – Lotus
    Commented May 18, 2017 at 15:04
  • 3
    $\begingroup$ SortBy[list, Last][[1,1]] $\endgroup$
    – nben
    Commented May 18, 2017 at 15:17

5 Answers 5

7
$\begingroup$

Have you seen MinimalBy?

SeedRandom[2]
v = RandomInteger[99, {7, 2}]

MinimalBy[v, Last]
{{92, 57}, {22, 84}, {63, 1}, {81, 96}, {19, 38}, {67, 68}, {63, 39}}

{{63, 1}}
$\endgroup$
5
$\begingroup$

First, I would like to say that MinimalBy (in the answers by @Mr. Wizard/@UnchartedWorks) is the cleanest way to solve the problem. It's too bad it's not optimized for arrays.

A small adjustment @MikeY's use of Ordering results in a tremendous performance improvement. I made a reference to it in a comment, but it seems it has not been appreciated in the way I expected. So I will demonstrate. Ordering[x, 1] is a special, optimized case that returns the position of the minimal element in x.

SeedRandom[2]
v = RandomInteger[10^9, {10^7, 2}];

v[[v[[All, 2]] ~Ordering~ 1]] // AbsoluteTiming
MinimalBy[v, Last] // AbsoluteTiming                    (* Mr. Wizard, UnchartedWorks) 
v[[Ordering[v[[All, 2]]] // First]] // AbsoluteTiming   (* another tweak of MikeY's *)
v[[Ordering[v[[All, 2]]]]] // First // AbsoluteTiming   (* MikeY *)
(*
  {0.188194, {{497087695, 12}}}
  {0.452981, {{497087695, 12}}}
  {2.19028, {497087695, 12}}
  {2.52904, {497087695, 12}}
*)

Note: Ordering[x, -1] is also a special optimized case that returns the position of the maximal element of x. Other cases of Ordering compute the complete ordering, which takes considerably longer. Ordering has been used in these ways in many answers on the site.

Ordering[v[[All, 2]], 1] // AbsoluteTiming        (* min position *)
Ordering[v[[All, 2]], -1] // AbsoluteTiming       (* max position *)
Ordering[v[[All, 2]]] // First // AbsoluteTiming  (* min position from complete ordering *)
Ordering[v[[All, 2]], {2}] // AbsoluteTiming      (* 2nd smallest position *)
Ordering[v[[All, 2]], 2] // AbsoluteTiming        (* two smallest positions *)
(*
  {0.188538, {8647676}}
  {0.194112, {323408}}
  {2.15685, 8647676}
  {2.16561, {8296548}}
  {2.16896, {8647676, 8296548}}
*)
$\endgroup$
4
$\begingroup$

Made up list

 lst = Table[RandomInteger[100, 2], {10}]

lst={{24, 100}, {2, 30}, {93, 26}, {37, 86}, {66, 71}, {92, 27}, {94, 25}, {16, 39}, {30, 68}, {65, 98}}

Pick off the element you want by ordering the list based on second column

lst[[Ordering[lst[[All, 2]]]]] // First

{94, 25}

Pick off just element 'a'

    lst[[Ordering[lst[[All, 2]]]]] // First// First

94

$\endgroup$
3
  • $\begingroup$ Have you seen the form Ordering[lst[[All, 2]], 1]? $\endgroup$
    – Michael E2
    Commented May 18, 2017 at 16:02
  • $\begingroup$ @Michael E2, definitely more terse $\endgroup$
    – MikeY
    Commented May 18, 2017 at 16:33
  • $\begingroup$ And faster when put inside lst[[..]] -- no reordering of the list. $\endgroup$
    – Michael E2
    Commented May 18, 2017 at 18:58
4
$\begingroup$

In:

SeedRandom[1];
xss = Table[RandomInteger[100, 2], {10}]
First @@ MinimalBy[xss, Last]

Out:

{{80, 14}, {0, 67}, {3, 65}, {100, 23}, {97, 68}, {74, 15}, {24, 
  4}, {100, 90}, {83, 70}, {1, 30}}
24
$\endgroup$
1
$\begingroup$
SeedRandom[2];
v = RandomInteger[99, {7, 2}];

First@SortBy[v, Last]
(* {63, 1} *)

also

Extract[#, Position[#[[All, 2]], Min[#[[All, 2]]]]] &@v
$\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.