From 1fb1bab78f2f736420ab1fb524be41a5bcaf3192 Mon Sep 17 00:00:00 2001 From: Jeffrey Tratner Date: Sun, 15 Sep 2013 12:50:11 -0400 Subject: [PATCH] BUG: fix sort_index with one col and ascending list now actually checks the first element of the list --- doc/source/release.rst | 4 ++++ pandas/core/frame.py | 7 ++++++- pandas/tests/test_frame.py | 19 ++++++++++++++++--- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/doc/source/release.rst b/doc/source/release.rst index e4143e3f76a25..793d52223b6f5 100644 --- a/doc/source/release.rst +++ b/doc/source/release.rst @@ -424,6 +424,10 @@ Bug Fixes across different versions of matplotlib (:issue:`4789`) - Suppressed DeprecationWarning associated with internal calls issued by repr() (:issue:`4391`) - Fixed an issue with a duplicate index and duplicate selector with ``.loc`` (:issue:`4825`) + - Fixed an issue with ``DataFrame.sort_index`` where, when sorting by a + single column and passing a list for ``ascending``, the argument for + ``ascending`` was being interpreted as ``True`` (:issue:`4839`, + :issue:`4846`) pandas 0.12.0 ------------- diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 75f81d20926a1..78ef806a45dcb 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -2856,7 +2856,7 @@ def sort_index(self, axis=0, by=None, ascending=True, inplace=False, Examples -------- - >>> result = df.sort_index(by=['A', 'B'], ascending=[1, 0]) + >>> result = df.sort_index(by=['A', 'B'], ascending=[True, False]) Returns ------- @@ -2875,6 +2875,9 @@ def sort_index(self, axis=0, by=None, ascending=True, inplace=False, raise ValueError('When sorting by column, axis must be 0 (rows)') if not isinstance(by, (tuple, list)): by = [by] + if com._is_sequence(ascending) and len(by) != len(ascending): + raise ValueError('Length of ascending (%d) != length of by' + ' (%d)' % (len(ascending), len(by))) if len(by) > 1: keys = [] @@ -2900,6 +2903,8 @@ def trans(v): raise ValueError('Cannot sort by duplicate column %s' % str(by)) indexer = k.argsort(kind=kind) + if isinstance(ascending, (tuple, list)): + ascending = ascending[0] if not ascending: indexer = indexer[::-1] elif isinstance(labels, MultiIndex): diff --git a/pandas/tests/test_frame.py b/pandas/tests/test_frame.py index 752fc4c58ff3a..6f6b3bf71c759 100644 --- a/pandas/tests/test_frame.py +++ b/pandas/tests/test_frame.py @@ -8796,24 +8796,37 @@ def test_sort_index(self): expected = frame.ix[frame.index[indexer]] assert_frame_equal(sorted_df, expected) + sorted_df = frame.sort(columns='A', ascending=False) + assert_frame_equal(sorted_df, expected) + + # GH4839 + sorted_df = frame.sort(columns=['A'], ascending=[False]) + assert_frame_equal(sorted_df, expected) + # check for now sorted_df = frame.sort(columns='A') + assert_frame_equal(sorted_df, expected[::-1]) expected = frame.sort_index(by='A') assert_frame_equal(sorted_df, expected) - sorted_df = frame.sort(columns='A', ascending=False) - expected = frame.sort_index(by='A', ascending=False) - assert_frame_equal(sorted_df, expected) sorted_df = frame.sort(columns=['A', 'B'], ascending=False) expected = frame.sort_index(by=['A', 'B'], ascending=False) assert_frame_equal(sorted_df, expected) + sorted_df = frame.sort(columns=['A', 'B']) + assert_frame_equal(sorted_df, expected[::-1]) + self.assertRaises(ValueError, frame.sort_index, axis=2, inplace=True) + msg = 'When sorting by column, axis must be 0' with assertRaisesRegexp(ValueError, msg): frame.sort_index(by='A', axis=1) + msg = r'Length of ascending \(5\) != length of by \(2\)' + with assertRaisesRegexp(ValueError, msg): + frame.sort_index(by=['A', 'B'], axis=0, ascending=[True] * 5) + def test_sort_index_multicolumn(self): import random A = np.arange(5).repeat(20)