Re: Ranks for an array of triplets
- To: mathgroup at smc.vnet.net
- Subject: [mg87535] Re: Ranks for an array of triplets
- From: Ray Koopman <koopman at sfu.ca>
- Date: Sat, 12 Apr 2008 07:00:36 -0400 (EDT)
- References: <ftncq8$8a9$1@smc.vnet.net>
On Apr 11, 2:59 am, Claus <clausena... at gmail.com> wrote:
> I can create an array with x,y,z triplets. x,y are on a regularly spaced
> raster, z is a RandomReal.
> For sorting the array according to the z values, I found two options,
> the second of which is significantly faster.
> However, my goal is not to sort, but to calculate the rank of the z
> value within the triplet.
> For example:
> original array Ar: {0,0,9.8},{0,1,2.3},{1,1,12.6}
> convert to: {0,0,2},{0,1,1},{1,1,3}
> $B"*(B 2.3 is the smallest z-value, hence it gets assigned rank 1
>
> In my case I can reach this converted array only with extra steps:
> - separating the z-values from Ar,
> - calculating the (standardized) "RanksOfAr",
> - "gluing" the triplets back together.
>
> Is there a way to to this in one step?
>
> Thanks,
> Claus
>
> Here is the mathematica code:
> -----------------------------
>
> Make up an array with (x, y) being coordinates and z being a value at
> that (x, y) location
>
> Ar = Partition[Flatten[Table[{i, j, k},
> {i, 1, 10}
> , {j, 1, 10}
> , {k, {RandomReal[]}}
> ]], 3];
>
> Time two versions of Sorting the array Ar according to z
>
> Timing[SortBottomAATriples = Sort[Ar, #1[[3]] < #2[[3]] &]];
>
> sll[ll_, elem_] := ll[[Ordering[ll[[All, elem]]]]]
> Timing[OrdBotAATrip = sll[Ar, 3]];
>
> Create the Ranks of z at the original position from Ar
>
> those ranks are scaled between [0, 1]
>
> RanksOfAr = Ordering[SortBottomAATriples]/Length[SortBottomAATriples];
>
> Procedure to put it all back together
>
> x = Ar[[All, 1]];
> y = Ar[[All, 2]];
> FinalAr = Transpose[{x, y, RanksOfAr}] // N;
Here's a smaller example of a method that should be faster:
In[1]:=
Ar = Flatten[Array[{##,Random[]}&,{nrows = 5, ncols = 4}],1]
Out[1]=
{{1,1,0.418682},{1,2,0.692552},{1,3,0.263399},{1,4,0.860788},
{2,1,0.379193},{2,2,0.339294},{2,3,0.293482},{2,4,0.842751},
{3,1,0.522699},{3,2,0.684685},{3,3,0.382372},{3,4,0.0906687},
{4,1,0.192081},{4,2,0.176807},{4,3,0.464003},{4,4,0.0851869},
{5,1,0.869599},{5,2,0.567554},{5,3,0.970354},{5,4,0.0748791}}
In[2]:=
N@MapThread[ReplacePart[#1,#2,3]&,
{Ar,Ordering@Ordering@Ar[[All,3]]/(nrows*ncols)}]
Out[2]=
{{1.,1.,0.55},{1.,2.,0.8},{1.,3.,0.3},{1.,4.,0.9},
{2.,1.,0.45},{2.,2.,0.4},{2.,3.,0.35},{2.,4.,0.85},
{3.,1.,0.65},{3.,2.,0.75},{3.,3.,0.5},{3.,4.,0.15},
{4.,1.,0.25},{4.,2.,0.2},{4.,3.,0.6},{4.,4.,0.1},
{5.,1.,0.95},{5.,2.,0.7},{5.,3.,1.},{5.,4.,0.05}}