diff --git a/doc/source/whatsnew/v0.19.0.txt b/doc/source/whatsnew/v0.19.0.txt index ec37b6d6f5f13..21dd56966f098 100644 --- a/doc/source/whatsnew/v0.19.0.txt +++ b/doc/source/whatsnew/v0.19.0.txt @@ -513,6 +513,7 @@ Other enhancements - ``Timestamp``, ``Period``, ``DatetimeIndex``, ``PeriodIndex`` and ``.dt`` accessor have gained a ``.is_leap_year`` property to check whether the date belongs to a leap year. (:issue:`13727`) - ``astype()`` will now accept a dict of column name to data types mapping as the ``dtype`` argument. (:issue:`12086`) - The ``pd.read_json`` and ``DataFrame.to_json`` has gained support for reading and writing json lines with ``lines`` option see :ref:`Line delimited json ` (:issue:`9180`) +- `Series.sort_index`` will now accept kwargs ``kind`` and ``na_position`` (:issue:`13589`) .. _whatsnew_0190.api: diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 2f78c9acf7972..cf2762dc49976 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -2022,6 +2022,9 @@ def sort_values(self, by, axis=0, ascending=True, inplace=False, Sort ascending vs. descending inplace : bool, default False if True, perform operation in-place + sort_remaining : bool, default True + if true and sorting by level and index is multilevel, sort by other + levels too (in order) after sorting by specified level kind : {'quicksort', 'mergesort', 'heapsort'}, default 'quicksort' Choice of sorting algorithm. See also ndarray.np.sort for more information. `mergesort` is the only stable algorithm. For @@ -2029,9 +2032,6 @@ def sort_values(self, by, axis=0, ascending=True, inplace=False, column or label. na_position : {'first', 'last'}, default 'last' `first` puts NaNs at the beginning, `last` puts NaNs at the end - sort_remaining : bool, default True - if true and sorting by level and index is multilevel, sort by other - levels too (in order) after sorting by specified level Returns ------- diff --git a/pandas/core/series.py b/pandas/core/series.py index 8379c8bcdcae8..6d8753df5b3a2 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -1773,7 +1773,7 @@ def _try_kind_sort(arr): @Appender(generic._shared_docs['sort_index'] % _shared_doc_kwargs) def sort_index(self, axis=0, level=None, ascending=True, inplace=False, - sort_remaining=True): + kind='quicksort', na_position='last', sort_remaining=True): axis = self._get_axis_number(axis) index = self.index @@ -1782,12 +1782,15 @@ def sort_index(self, axis=0, level=None, ascending=True, inplace=False, sort_remaining=sort_remaining) elif isinstance(index, MultiIndex): from pandas.core.groupby import _lexsort_indexer - indexer = _lexsort_indexer(index.labels, orders=ascending) + indexer = _lexsort_indexer(index.labels, orders=ascending, + na_position=na_position) indexer = _ensure_platform_int(indexer) new_index = index.take(indexer) else: new_index, indexer = index.sort_values(return_indexer=True, - ascending=ascending) + ascending=ascending, + kind=kind, + na_position=na_position) new_values = self._values.take(indexer) result = self._constructor(new_values, index=new_index) diff --git a/pandas/tests/series/test_sorting.py b/pandas/tests/series/test_sorting.py index 826201adbdb50..6af284417a15a 100644 --- a/pandas/tests/series/test_sorting.py +++ b/pandas/tests/series/test_sorting.py @@ -5,7 +5,7 @@ from pandas import (DataFrame, Series, MultiIndex) -from pandas.util.testing import (assert_series_equal, assert_almost_equal) +from pandas.util.testing import (assert_series_equal, assert_almost_equal, assertRaisesRegexp) import pandas.util.testing as tm from .common import TestData @@ -144,3 +144,22 @@ def test_sort_index_multiindex(self): # rows share same level='A': sort has no effect without remaining lvls res = s.sort_index(level='A', sort_remaining=False) assert_series_equal(s, res) + + def test_sort_index_nan(self): + + # GH13729 + ser = Series(['A', np.nan, 'C', 'D'], [1, 2, 0, np.nan]) + + # na_position='last', kind='quicksort' + result = ser.sort_index(kind='quicksort', na_position='last') + expected = Series(['C', 'A', np.nan, 'D'], [0, 1, 2, np.nan]) + assert_series_equal(result, expected) + + # na_position='first' + result = ser.sort_index(na_position='first') + expected = Series(['D', 'C', 'A', np.nan], [np.nan, 0, 1, 2]) + assert_series_equal(result, expected) + + # invalid argument + assertRaisesRegexp(TypeError, 'got an unexpected keyword argument', + ser.sort_index, arg='first')