1D array sorting ascending and descending by fields

Hi! I have a one-dimensional ndarray with two fields. I'd like to sort in descending order by field 'a', breaking ties by sorting in ascending order by field 'b'. I've found combinations of sorting and reversing followed by stable sorting that work, but there must be a straightforward way to do it. Your help is appreciated! Thank you, Patrick

Here's how I sorted primarily by field 'a' descending and secondarily by field 'b' ascending: (Note that 'a' is the second column, 'b' is the first)
data array([('b', 0.03), ('c', 0.03), ('f', 0.03), ('e', 0.01), ('d', 0.04), ('a', 0.04)], dtype=[('b', '|S32'), ('a', '<f8')]) data.sort(order='b') # sort by b data = data[::-1] # reverse data[numpy.argsort(data['a'])][::-1] # sort by a and reverse array([('a', 0.04), ('d', 0.04), ('b', 0.03), ('c', 0.03), ('f', 0.03), ('e', 0.01)], dtype=[('b', '|S32'), ('a', '<f8')])
My question is whether there's an easier way to do this. Originally I thought it would be possible to just do:
data.sort(order=('-a', 'b'))
...indicating that the order of 'a' is descending, but this isn't part of NumPy's sort behavior. Your help is appreciated! Thank you, Patrick

On Mon, Jun 4, 2012 at 11:10 AM, Patrick Redmond <plredmond@gmail.com> wrote:
Here's how I sorted primarily by field 'a' descending and secondarily by field 'b' ascending:
could you multiply the numeric field by -1, sort, then put it back -- somethign like: data *- -1 data_sorted = np.sort(data, order=['a','b']) data_sorted *= -1 (reverse if necessary -- I lost track...) -Chris
(Note that 'a' is the second column, 'b' is the first)
data array([('b', 0.03), ('c', 0.03), ('f', 0.03), ('e', 0.01), ('d', 0.04), ('a', 0.04)], dtype=[('b', '|S32'), ('a', '<f8')]) data.sort(order='b') # sort by b data = data[::-1] # reverse data[numpy.argsort(data['a'])][::-1] # sort by a and reverse array([('a', 0.04), ('d', 0.04), ('b', 0.03), ('c', 0.03), ('f', 0.03), ('e', 0.01)], dtype=[('b', '|S32'), ('a', '<f8')])
My question is whether there's an easier way to do this.
could you multipily the nubmeric field by -1, sort, then multiply it again? Originally I
thought it would be possible to just do:
data.sort(order=('-a', 'b'))
...indicating that the order of 'a' is descending, but this isn't part of NumPy's sort behavior.
Your help is appreciated!
Thank you, Patrick
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
-- Christopher Barker, Ph.D. Oceanographer Emergency Response Division NOAA/NOS/OR&R (206) 526-6959 voice 7600 Sand Point Way NE (206) 526-6329 fax Seattle, WA 98115 (206) 526-6317 main reception Chris.Barker@noaa.gov

On Monday, June 4, 2012, Chris Barker wrote:
On Mon, Jun 4, 2012 at 11:10 AM, Patrick Redmond <plredmond@gmail.com<javascript:;>> wrote:
Here's how I sorted primarily by field 'a' descending and secondarily by field 'b' ascending:
could you multiply the numeric field by -1, sort, then put it back -- somethign like:
data *- -1 data_sorted = np.sort(data, order=['a','b']) data_sorted *= -1
(reverse if necessary -- I lost track...)
-Chris
While that may work for this users case, that would not work for all dtypes. Some, such as timedelta, datetime and strings would not be able to be multiplied by a number. Would be an interesting feature to add, but I am not certain if the negative sign notation would be best. Is it possible for a named field to start with a negative sign? Ben Root

On Tue, Jun 5, 2012 at 1:17 AM, Benjamin Root <ben.root@ou.edu> wrote:
On Monday, June 4, 2012, Chris Barker wrote:
On Mon, Jun 4, 2012 at 11:10 AM, Patrick Redmond <plredmond@gmail.com> wrote:
Here's how I sorted primarily by field 'a' descending and secondarily by field 'b' ascending:
could you multiply the numeric field by -1, sort, then put it back -- somethign like:
data *- -1 data_sorted = np.sort(data, order=['a','b']) data_sorted *= -1
(reverse if necessary -- I lost track...)
-Chris
While that may work for this users case, that would not work for all dtypes. Some, such as timedelta, datetime and strings would not be able to be multiplied by a number.
Would be an interesting feature to add, but I am not certain if the negative sign notation would be best. Is it possible for a named field to start with a negative sign?
Maybe add a reverse= argument (named after the corresponding argument to list.sort and __builtins__.sorted). # sorts in descending order, no fields required np.sort([10, 20, 0], reverse=True) # sorts in descending order np.sort(rec_array, order=("a", "b"), reverse=True) # ascending by "a" then descending by "b" np.sort(rec_array, order=("a", "b"), reverse=(False, True)) ? -n

On Tue, Jun 5, 2012 at 10:49 AM, Nathaniel Smith <njs@pobox.com> wrote:
On Tue, Jun 5, 2012 at 1:17 AM, Benjamin Root <ben.root@ou.edu> wrote:
On Monday, June 4, 2012, Chris Barker wrote:
On Mon, Jun 4, 2012 at 11:10 AM, Patrick Redmond <plredmond@gmail.com> wrote:
Here's how I sorted primarily by field 'a' descending and secondarily
field 'b' ascending:
could you multiply the numeric field by -1, sort, then put it back -- somethign like:
data *- -1 data_sorted = np.sort(data, order=['a','b']) data_sorted *= -1
(reverse if necessary -- I lost track...)
-Chris
While that may work for this users case, that would not work for all
by dtypes.
Some, such as timedelta, datetime and strings would not be able to be multiplied by a number.
Would be an interesting feature to add, but I am not certain if the negative sign notation would be best. Is it possible for a named field to start with a negative sign?
Maybe add a reverse= argument (named after the corresponding argument to list.sort and __builtins__.sorted).
# sorts in descending order, no fields required np.sort([10, 20, 0], reverse=True) # sorts in descending order np.sort(rec_array, order=("a", "b"), reverse=True) # ascending by "a" then descending by "b" np.sort(rec_array, order=("a", "b"), reverse=(False, True))
?
-n
Clear, unambiguous, and works with the existing framework. +1 Ben Root

On Mon, Jun 4, 2012 at 6:08 PM, Chris Barker <chris.barker@noaa.gov> wrote:
could you multiply the numeric field by -1, sort, then put it back
Yeah, that works great for my situation. Thanks Chris! On Mon, Jun 4, 2012 at 8:17 PM, Benjamin Root <ben.root@ou.edu> wrote:
While that may work for this users case, that would not work for all dtypes. Some, such as timedelta, datetime and strings would not be able to be multiplied by a number.
This is the reason why I thought there might be such a feature.
Would be an interesting feature to add, but I am not certain if the negative sign notation would be best. Is it possible for a named field to start with a negative sign?
I'm not sure about what is allowable in names, but I would be interested in getting involved with the NumPy project by helping to add this feature. I'll check out the contributing doc.
participants (4)
-
Benjamin Root
-
Chris Barker
-
Nathaniel Smith
-
Patrick Redmond