The following, suprisingly, is almost as fast as Mr.Wizard's approach, and it provides added flexibility to get ranks different from Min
and Max
or ranges of ranks as well as the ability to specify any ordering function:
{#[[Ordering[#, 1]]], #[[Ordering[#, -1]]]} & /@ Transpose[dat]
Alternatively, one can re-organize the left part:
#[[Flatten@{Ordering[#, 1], Ordering[#, -1]}]] & /@ Transpose[dat]
Additional flexibility comes from the ability to use the second and third arguments of Ordering
.
To get the second smallest and third largest elements, use as
{#[[Ordering[#, 2]]], #[[Ordering[#, -3]]]} & /@ Transpose[dat]
To get the bottom 4 and top 5 elements:
{#[[Ordering[#, {1,4}]]], #[[Ordering[#, {-5,-1}]]]} & /@ Transpose[dat]
To get odd-ranked and even-ranked elements:
{#[[Ordering[#, {1,-1,2}]]], #[[Ordering[#, {2,-1,2}]]]} & /@ Transpose[dat]
To get the smallest and largest elements when elements are ordered by Abs
:
{#[[Ordering[#, 1, Abs[#1] < Abs[#2] &]]],
#[[Ordering[#, -1,Abs[#1] < Abs[#2] &]]]} & /@ Transpose[dat]
etc...