From: Canopus56 on
I have a list of x, y, z triples in the form:
{{350.17,-43.6426,1768. 77},{350.17,-43.5582,1259.67},{350.17,-43.5308,967.89},{350.17,-43.5839,1689.8},{350.17,-43.6445,1753.05},{350.17,-43.6114,2021.65},{350.17,-43.5327,977.36},{350.17,-43.5601,1289.87},{350.17,-43.5858,1720.39},{350.17,-43.6464,1736.25}}
How do I sort a nested list where I want the sort order to be major x-ascending, minor subsort with y-ascending?
Thanks, Kurt

From: Leonid Shifrin on
Hi Kurt,

Here is your data:

In[2]:= data = {{350.17, -43.6426, 1768.77}, {350.17, -43.5582,
1259.67}, {350.17, -43.5308, 967.89}, {350.17, -43.5839,
1689.8}, {350.17, -43.6445, 1753.05}, {350.17, -43.6114,
2021.65}, {350.17, -43.5327, 977.36}, {350.17, -43.5601,
1289.87}, {350.17, -43.5858, 1720.39}, {350.17, -43.6464, 1736.25}};

Here is a brute force solution

In[66]:= sorted =
Sort[data, #1[[1]] < #2[[1]] || (#1[[1]] == #2[[1]] && #1[[2]] < #2[[2]])
&]

Out[66]= {{350.17, -43.6464, 1736.25}, {350.17, -43.6445,
1753.05}, {350.17, -43.6426, 1768.77}, {350.17, -43.6114,
2021.65}, {350.17, -43.5858, 1720.39}, {350.17, -43.5839,
1689.8}, {350.17, -43.5601, 1289.87}, {350.17, -43.5582,
1259.67}, {350.17, -43.5327, 977.36}, {350.17, -43.5308, 967.89}}

Here is another one, using canonical sort

In[68]:= sortedAlt = data[[Ordering[data[[All, {1, 2}]]]]]

Out[68]= {{350.17, -43.6464, 1736.25}, {350.17, -43.6445,
1753.05}, {350.17, -43.6426, 1768.77}, {350.17, -43.6114,
2021.65}, {350.17, -43.5858, 1720.39}, {350.17, -43.5839,
1689.8}, {350.17, -43.5601, 1289.87}, {350.17, -43.5582,
1259.67}, {350.17, -43.5327, 977.36}, {350.17, -43.5308, 967.89}}


The results will not generally be identical since your instruction does not
specify how to
compare elements for which both first and second numbers are the same, and
the two methods
treat them differently. If this does not matter to you, I'd recommend the
second method
since it offers considerable speed advantage on large lists:

In[62]:= largeData = RandomInteger[{1, 10}, {100000, 3}];

In[63]:= (largeSorted =
Sort[largeData, (#1[[1]] < #2[[1]]) || (#1[[1]] == #2[[1]] && \
#1[[2]] < #2[[2]]) &]); // Timing

Out[63]= {6.86, Null}

In[64]:= (largeSortedAlt =
largeData[[Ordering[largeData[[All, {1, 2}]]]]]); // Timing

Out[64]= {0.031, Null}

In this benchmark, the second method is about 200 times faster than the
first. In the first method, you can improve efficiency somewhat by compiling
your comparison function:

In[69]:= compF =
Compile[{{x, _Real, 1}, {y, _Real, 1}},
(x[[1]] < y[[1]]) || (x[[1]] == y[[1]] && x[[2]] < y[[2]])]

In[70]:= Sort[largeData, compF]; // Timing

Out[70]= {2.032, Null}

Hope this helps.

Regards,
Leonid



On Fri, Mar 19, 2010 at 10:46 AM, Canopus56 <canopus56(a)yahoo.com> wrote:

> I have a list of x, y, z triples in the form:
> {{350.17,-43.6426,1768.
> 77},{350.17,-43.5582,1259.67},{350.17,-43.5308,967.89},{350.17,-43.5839,1689.8},{350.17,-43.6445,1753.05},{350.17,-43.6114,2021.65},{350.17,-43.5327,977.36},{350.17,-43.5601,1289.87},{350.17,-43.5858,1720.39},{350.17,-43.6464,1736.25}}
> How do I sort a nested list where I want the sort order to be major
> x-ascending, minor subsort with y-ascending?
> Thanks, Kurt
>
>


From: Bob Hanlon on

Sort[SortBy[data, #[[2]] &]]

or

SortBy[data, {#[[1]], #[[2]]} &]

or

SortBy[data, {First, #[[2]] &}]


Bob Hanlon

---- Canopus56 <canopus56(a)yahoo.com> wrote:

=============
I have a list of x, y, z triples in the form:
{{350.17,-43.6426,1768. 77},{350.17,-43.5582,1259.67},{350.17,-43.5308,967.89},{350.17,-43.5839,1689.8},{350.17,-43.6445,1753.05},{350.17,-43.6114,2021.65},{350.17,-43.5327,977.36},{350.17,-43.5601,1289.87},{350.17,-43.5858,1720.39},{350.17,-43.6464,1736.25}}
How do I sort a nested list where I want the sort order to be major x-ascending, minor subsort with y-ascending?
Thanks, Kurt



From: Canopus56 on
Thanks to all who replied on this thread. - Kurt




 | 
Pages: 1
Prev: solving equations
Next: Random`DistributionVector