Re: Sorting nested lists
- To: mathgroup at smc.vnet.net
- Subject: [mg108480] Re: Sorting nested lists
- From: Leonid Shifrin <lshifr at gmail.com>
- Date: Fri, 19 Mar 2010 06:45:20 -0500 (EST)
- References: <201003190746.CAA08430@smc.vnet.net>
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 at 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
>
>
- References:
- Sorting nested lists
- From: Canopus56 <canopus56@yahoo.com>
- Sorting nested lists