-
-
Notifications
You must be signed in to change notification settings - Fork 18.7k
REF/BUG/API: factorizing categorical data #19938
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
18de376
9ef5be2
5e52b6f
e19ae86
121b682
a6bc405
0bfbc47
b25f383
2688c4f
2395a99
ab4f01c
65150f4
ad8173b
1e006d1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -507,7 +507,7 @@ def factorize(values, sort=False, order=None, na_sentinel=-1, size_hint=None): | |
|
||
if is_categorical_dtype(values): | ||
values = getattr(values, '_values', values) | ||
labels, uniques = values.factorize(sort=sort) | ||
labels, uniques = values.factorize() | ||
dtype = original.dtype | ||
else: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. shouldn't this actually be a check on the values if they have a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This PR is just a bugfix for categorical. But the structure will be very similar (I'll just change I'll implement EA.factorize today hopefully, but have to get things like unique and argsort working first. |
||
values, dtype, _ = _ensure_data(values) | ||
|
@@ -516,8 +516,14 @@ def factorize(values, sort=False, order=None, na_sentinel=-1, size_hint=None): | |
na_sentinel=na_sentinel, | ||
size_hint=size_hint) | ||
|
||
if sort and len(uniques) > 0: | ||
from pandas.core.sorting import safe_sort | ||
if sort and len(uniques) > 0: | ||
from pandas.core.sorting import safe_sort | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. could move to the except (but no big deal) |
||
try: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removed all the sorting from Categorical.factorize. All that logic is here. I don't think we want to just call
On some small bencharks (10,000 elements) this is about 25-40% faster. The only slow case, for which we still need safe_sort, is when the array is mixed. In that case things are about 10% slower. |
||
order = uniques.argsort() | ||
labels = take_1d(order, labels, fill_value=na_sentinel) | ||
uniques = uniques.take(order) | ||
except TypeError: | ||
# Mixed types, where uniques.argsort fails. | ||
uniques, labels = safe_sort(uniques, labels, | ||
na_sentinel=na_sentinel, | ||
assume_unique=True) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2069,7 +2069,7 @@ def unique(self): | |
take_codes = sorted(take_codes) | ||
return cat.set_categories(cat.categories.take(take_codes)) | ||
|
||
def factorize(self, sort=False, na_sentinel=-1): | ||
def factorize(self, na_sentinel=-1): | ||
"""Encode the Categorical as an enumerated type. | ||
|
||
Parameters | ||
|
@@ -2110,7 +2110,7 @@ def factorize(self, sort=False, na_sentinel=-1): | |
[a, b] | ||
Categories (2, object): [a, b] | ||
""" | ||
from pandas.core.algorithms import _factorize_array, take_1d | ||
from pandas.core.algorithms import _factorize_array | ||
|
||
codes = self.codes.astype('int64') | ||
codes[codes == -1] = iNaT | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The interface we have to I think its worth re-factoring this (maybe before this PR), though I suppose could be after. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, that'd be nicer. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do we actually want this to be public? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. factorize in general? I don’t see why not. It’s present on series and index. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. #19938 (comment) was in reference to the API docs. We whitelist the methods on Categorical that are included in the API docs (just |
||
|
@@ -2121,10 +2121,6 @@ def factorize(self, sort=False, na_sentinel=-1): | |
uniques = self._constructor(self.categories.take(uniques), | ||
categories=self.categories, | ||
ordered=self.ordered) | ||
if sort: | ||
order = uniques.argsort() | ||
labels = take_1d(order, labels, fill_value=na_sentinel) | ||
uniques = uniques.take(order) | ||
return labels, uniques | ||
|
||
def equals(self, other): | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see my comment below, but you might simpy dispatch on categricals and just return, mixing the impl is really confusing here.