Repository: pandas-dev/pandas

Issue:
BUG: Accept kwargs kind and na_position in Series.sort_index (GH13589)
- [x] closes #13589 
- [x] tests added / passed
- [x] whatsnew entry

/cc @jreback 



Discussion:
you always needs tests 

@jreback I'm not sure what to add in tests for this one. Can you please help me here?

you are adding keywords so need tests - look at what Dataframe tests for snd mirror those 

I tried looking into `test_frame.py`. It has no test containing `kind` or `na_position`. Am I missing something or looking at wrong place?

rebase on master you have a really old master 
just recursive grep

> just recursive grep

Thanks for the hint, @jreback. Please check the tests I have added if they are sufficient or not.

@jreback Is this fine?

@sahildua2305 Only a few small comments, for the rest this is already looking fine!

@jorisvandenbossche I've updated the PR. Please check if it's good now.

can you rebase / update?

Yes! I'll do so. 


Resolving patch:
diff --git a/pandas/core/generic.py b/pandas/core/generic.py
--- a/pandas/core/generic.py
+++ b/pandas/core/generic.py
@@ -2029,7 +2029,8 @@ def sort_values(self, by, axis=0, ascending=True, inplace=False,
              DataFrames, this option is only applied when sorting on a single
              column or label.
         na_position : {'first', 'last'}, default 'last'
-             `first` puts NaNs at the beginning, `last` puts NaNs at the end
+             `first` puts NaNs at the beginning, `last` puts NaNs at the end.
+             Not implemented for MultiIndex.
         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
diff --git a/pandas/core/series.py b/pandas/core/series.py
--- 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
@@ -1783,11 +1783,13 @@ def sort_index(self, axis=0, level=None, ascending=True, inplace=False,
         elif isinstance(index, MultiIndex):
             from pandas.core.groupby import _lexsort_indexer
             indexer = _lexsort_indexer(index.labels, orders=ascending)
-            indexer = _ensure_platform_int(indexer)
-            new_index = index.take(indexer)
         else:
-            new_index, indexer = index.sort_values(return_indexer=True,
-                                                   ascending=ascending)
+            from pandas.core.groupby import _nargsort
+            indexer = _nargsort(index, kind=kind, ascending=ascending,
+                                na_position=na_position)
+
+        indexer = _ensure_platform_int(indexer)
+        new_index = index.take(indexer)
 
         new_values = self._values.take(indexer)
         result = self._constructor(new_values, index=new_index)


Test patch:
diff --git a/pandas/tests/series/test_sorting.py b/pandas/tests/series/test_sorting.py
--- a/pandas/tests/series/test_sorting.py
+++ b/pandas/tests/series/test_sorting.py
@@ -144,3 +144,28 @@ 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_kind(self):
+        # GH #14444 & #13589:  Add support for sort algo choosing
+        series = Series(index=[3, 2, 1, 4, 3])
+        expected_series = Series(index=[1, 2, 3, 3, 4])
+
+        index_sorted_series = series.sort_index(kind='mergesort')
+        assert_series_equal(expected_series, index_sorted_series)
+
+        index_sorted_series = series.sort_index(kind='quicksort')
+        assert_series_equal(expected_series, index_sorted_series)
+
+        index_sorted_series = series.sort_index(kind='heapsort')
+        assert_series_equal(expected_series, index_sorted_series)
+
+    def test_sort_index_na_position(self):
+        series = Series(index=[3, 2, 1, 4, 3, np.nan])
+
+        expected_series_first = Series(index=[np.nan, 1, 2, 3, 3, 4])
+        index_sorted_series = series.sort_index(na_position='first')
+        assert_series_equal(expected_series_first, index_sorted_series)
+
+        expected_series_last = Series(index=[1, 2, 3, 3, 4, np.nan])
+        index_sorted_series = series.sort_index(na_position='last')
+        assert_series_equal(expected_series_last, index_sorted_series)