Skip to content

Commit 5cc1025

Browse files
chris-b1jreback
authored andcommitted
BUG: kind parameter on categorical argsort (pandas-dev#16834)
1 parent 8d197ba commit 5cc1025

File tree

6 files changed

+24
-7
lines changed

6 files changed

+24
-7
lines changed

doc/source/whatsnew/v0.20.3.txt

+1
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ Numeric
9494
Categorical
9595
^^^^^^^^^^^
9696

97+
- Bug in ``DataFrame.sort_values`` not respecting the ``kind`` with categorical data (:issue:`16793`)
9798

9899
Other
99100
^^^^^

pandas/compat/numpy/function.py

+9-1
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,14 @@ def validate_argmax_with_skipna(skipna, args, kwargs):
107107
validate_argsort = CompatValidator(ARGSORT_DEFAULTS, fname='argsort',
108108
max_fname_arg_count=0, method='both')
109109

110+
# two different signatures of argsort, this second validation
111+
# for when the `kind` param is supported
112+
ARGSORT_DEFAULTS_KIND = OrderedDict()
113+
ARGSORT_DEFAULTS_KIND['axis'] = -1
114+
ARGSORT_DEFAULTS_KIND['order'] = None
115+
validate_argsort_kind = CompatValidator(ARGSORT_DEFAULTS_KIND, fname='argsort',
116+
max_fname_arg_count=0, method='both')
117+
110118

111119
def validate_argsort_with_ascending(ascending, args, kwargs):
112120
"""
@@ -121,7 +129,7 @@ def validate_argsort_with_ascending(ascending, args, kwargs):
121129
args = (ascending,) + args
122130
ascending = True
123131

124-
validate_argsort(args, kwargs, max_fname_arg_count=1)
132+
validate_argsort_kind(args, kwargs, max_fname_arg_count=3)
125133
return ascending
126134

127135

pandas/core/categorical.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1288,7 +1288,7 @@ def check_for_ordered(self, op):
12881288
"you can use .as_ordered() to change the "
12891289
"Categorical to an ordered one\n".format(op=op))
12901290

1291-
def argsort(self, ascending=True, *args, **kwargs):
1291+
def argsort(self, ascending=True, kind='quicksort', *args, **kwargs):
12921292
"""
12931293
Returns the indices that would sort the Categorical instance if
12941294
'sort_values' was called. This function is implemented to provide
@@ -1309,7 +1309,7 @@ def argsort(self, ascending=True, *args, **kwargs):
13091309
numpy.ndarray.argsort
13101310
"""
13111311
ascending = nv.validate_argsort_with_ascending(ascending, args, kwargs)
1312-
result = np.argsort(self._codes.copy(), **kwargs)
1312+
result = np.argsort(self._codes.copy(), kind=kind, **kwargs)
13131313
if not ascending:
13141314
result = result[::-1]
13151315
return result

pandas/core/sorting.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ def nargsort(items, kind='quicksort', ascending=True, na_position='last'):
233233

234234
# specially handle Categorical
235235
if is_categorical_dtype(items):
236-
return items.argsort(ascending=ascending)
236+
return items.argsort(ascending=ascending, kind=kind)
237237

238238
items = np.asanyarray(items)
239239
idx = np.arange(len(items))

pandas/tests/frame/test_sorting.py

+9
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,15 @@ def test_stable_descending_multicolumn_sort(self):
238238
kind='mergesort')
239239
assert_frame_equal(sorted_df, expected)
240240

241+
def test_stable_categorial(self):
242+
# GH 16793
243+
df = DataFrame({
244+
'x': pd.Categorical(np.repeat([1, 2, 3, 4], 5), ordered=True)
245+
})
246+
expected = df.copy()
247+
sorted_df = df.sort_values('x', kind='mergesort')
248+
assert_frame_equal(sorted_df, expected)
249+
241250
def test_sort_datetimes(self):
242251

243252
# GH 3461, argsort / lexsort differences for a datetime column

pandas/tests/test_categorical.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -585,9 +585,8 @@ def test_numpy_argsort(self):
585585
tm.assert_numpy_array_equal(np.argsort(c), expected,
586586
check_dtype=False)
587587

588-
msg = "the 'kind' parameter is not supported"
589-
tm.assert_raises_regex(ValueError, msg, np.argsort,
590-
c, kind='mergesort')
588+
tm.assert_numpy_array_equal(np.argsort(c, kind='mergesort'), expected,
589+
check_dtype=False)
591590

592591
msg = "the 'axis' parameter is not supported"
593592
tm.assert_raises_regex(ValueError, msg, np.argsort,

0 commit comments

Comments
 (0)