Position of n largest elements in each row in a matrix that satisfies certain criterion

Update: Shorter variations:

ClearAll[taken, takem, takek]
taken[condition_, n_] := Apply[Join] @*
  MapIndexed[Thread[{#2[[1]], 
    Select[Function[x, condition @ #[[x]]]] @ TakeLargest[# -> "Index", n]}] &]

takem[condition_, m_] := Apply[Join] @*
  MapIndexed[Thread[{#2[[1]], 
    Select[Function[x, condition @ #[[x]]]] @ Ordering[#, -m]}] &]

takek[condition_, k_] := MapIndexed[Sequence @@ Thread[{#2[[1]], #}] &] @*
  Map[Cases[{a_ /; condition[a], b_} :> b] @
      Nearest[# -> {"Element", "Index"}, Max @ #, k] &]

Examples:

taken[GreaterEqualThan[1/2], 2] @ m
{{1, 3}, {1, 2}, {2, 1}}
takem[GreaterEqualThan[1/2], 2] @ m
{{1, 3}, {1, 2}, {2, 1}}
takek[GreaterEqualThan[1/2], 2] @ m
{{1, 3}, {1, 2}, {2, 1}}

Original answer:

ClearAll[take]
take[condition_, n_] := Apply[Join] @* 
  MapIndexed[Thread[{#2[[1]], #}] &] @*
  Map[Map[#Index &] @
   Select[condition @ #Element &] @
   TakeLargest[# -> All, n]&]

Examples:

take[GreaterEqualThan[1/2], 2] @ m
{{1, 3}, {1, 2}, {2, 1}}
take[GreaterEqualThan[0], 2] @ m
{{1, 3}, {1, 2}, {2, 1}, {2, 3}} 
take[GreaterEqualThan[2], 3] @ {Range[5], Range[-3, 2], Reverse @ Range[4, 8]}
{{1, 5}, {1, 4}, {1, 3}, {2, 6}, {3, 1}, {3, 2}, {3, 3}} 

TakeLargest is the function you are looking for. And then Select to get the numbers above 1/2:

m = {{1, 2, 3}, {3, -2, 1/3}};
t = TakeLargest[#, 2] & /@ m
sel=Select[# > 1/2 &] /@ t

(*{{3, 2}, {3}}*)

And then finally the positions. We first determine the position inside sel and then prepend the row number:

pos = Flatten /@ MapThread[Function[{x, y}, Position[x, #] & /@ y], {m, sel}]
MapIndexed[Function[{x, y}, {Sequence @@ y, #} & /@ x], pos]

(* {{{1, 3}, {1, 2}}, {{2, 1}}} *)

Tags:

Matrix