0
$\begingroup$

I have this matrix...

mat = Table[{k, 0}, {k, 0, limit}];

After a series of dynamic iterative operations, some of the 0 initialized entries (i.e., those of the 2nd column of mat, i.e., mat[[All, 2]]) are replaced w/ positive integers, e.g.,

mat = {{0,78},{1,0},{2,0},{3,11},{4,11},{5,11},...,{limit,0}}

I realize that there are several standard ways for retrieving the nth minimum value of mat[[All, 2]] but, since mat has so many 0s, they do not help me.

I am looking for a standard/elegant/efficient way to find the nth UNIQUE min value of mat, along w/ its associated row index, e.g., if limit = 6 & I wanted to find the 2nd min-value/index pair, executing...

Print[UniqueMin[mat[[All, 2]], 2]];

would output...

{4,11}

Bc 11 was the 2nd smallest unique value in mat & row 4 was where it 1st occurred.

$\endgroup$
2
  • $\begingroup$ Why {4,11}, not {3,11}? $\endgroup$
    – corey979
    Apr 15, 2019 at 6:25
  • $\begingroup$ @corey979 Bc Mathematica starts index @ 1, not 0. You'd be right, if I was asking for the associated row value, but I asked for the associated row index. $\endgroup$
    – Landon
    Apr 15, 2019 at 6:39

2 Answers 2

1
$\begingroup$
UniqueMin[list_?VectorQ, n_Integer?Positive] :=
 Module[{min = Union[list][[n]]},
  {Position[list, min][[1, 1]], min}]

mat = {{0, 78}, {1, 0}, {2, 0}, {3, 11}, {4, 11}, {5, 11}};

UniqueMin[mat[[All, 2]], 2]

(* {4, 11} *)
$\endgroup$
0
$\begingroup$

An alternative approach would use PositionIndex followed by KeySort

The variants below differ in either accessing the parts of the result or using a pattern match (which is slightly slower)

(* version 1*)
Clear[UniqueMin]

UniqueMin[list_?VectorQ, n_Integer?Positive] := With[
  {entry = Take[#, {n}]& @ KeySort @ PositionIndex @ list},
  {entry[[1, 1]], Keys[entry][[1]]}]

UniqueMin[mat[[All, 2]], 2]
(* {4, 11} *)


(* version 2 *)
Clear[UniqueMin]

UniqueMin[list_?VectorQ, n_Integer?Positive] := 
 With[{entry = Take[#, {n}]& @ KeySort @ PositionIndex @ list}, 
  Replace[entry, Association[Rule[x_, List[y_, ___]]] :> {y, x}]]

UniqueMin[mat[[All, 2]], 2]
(* {4, 11} *)

```
$\endgroup$

Your Answer

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

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