[Numpy-discussion] lexsort

Anne Archibald peridot.faceted at gmail.com
Tue May 6 18:35:26 EDT 2008


2008/5/6 Eleanor <e.howick at irl.cri.nz>:
> >>> a = numpy.array([[1,2,6], [2,2,8], [2,1,7],[1,1,5]])
>  >>> a
>  array([[1, 2, 6],
>        [2, 2, 8],
>        [2, 1, 7],
>        [1, 1, 5]])
>  >>> indices = numpy.lexsort(a.T)
>  >>> a.T.take(indices,axis=-1).T
>  array([[1, 1, 5],
>        [1, 2, 6],
>        [2, 1, 7],
>        [2, 2, 8]])
>
>
>  The above does what I want, equivalent to sorting on column A then
>  column B in Excel, but al the transposes are ungainly. I've stared at it a while
>  but can't come up with a more elegant solution. Any ideas?

It appears that lexsort is broken in several ways, and its docstring
is misleading.

First of all, this code is not doing quite what you describe. The
primary key here is the [5,6,7,8] column, followed by the middle and
then by the first. This is almost exactly the opposite of what you
describe (and of what I expected). To get this to sort the way you
describe, the clearest way is to write a sequence:

In [34]: indices = np.lexsort( (a[:,1],a[:,0]) )

In [35]: a[indices,:]
Out[35]:
array([[1, 1, 5],
       [1, 2, 6],
       [2, 1, 7],
       [2, 2, 8]])

In other words,sort over a[:,1], then sort again over a[:,0], making
a[:,0] the primary key. I have used "fancy indexing" to pull the array
into the right order, but it can also be done with take():

In [40]: np.take(a,indices,axis=0)
Out[40]:
array([[1, 1, 5],
       [1, 2, 6],
       [2, 1, 7],
       [2, 2, 8]])


As for why I say lexsort() is broken, well, it simply returns 0 for
higher-rank arrays (rather than either sorting or raising an
exception), it raises an exception when handed axis=None rather than
flattening as the docstring claims, and whatever the axis argument is
supposed to do, it doesn't seem to do it:

In [44]: np.lexsort(a,axis=0)
Out[44]: array([1, 0, 2])

In [45]: np.lexsort(a,axis=-1)
Out[45]: array([1, 0, 2])

In [46]: np.lexsort(a,axis=1)
---------------------------------------------------------------------------
<type 'exceptions.ValueError'>            Traceback (most recent call last)

/home/peridot/<ipython console> in <module>()

<type 'exceptions.ValueError'>: axis(=1) out of bounds


Anne



More information about the NumPy-Discussion mailing list