Skip to content

Commit 3e96734

Browse files
committed
PERF: For GH23814, return early in Categorical.__init__
1 parent 89871a0 commit 3e96734

File tree

2 files changed

+14
-0
lines changed

2 files changed

+14
-0
lines changed

asv_bench/benchmarks/categoricals.py

+4
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ def setup(self):
4646
self.values_some_nan = list(np.tile(self.categories + [np.nan], N))
4747
self.values_all_nan = [np.nan] * len(self.values)
4848
self.values_all_int8 = np.ones(N, 'int8')
49+
self.categorical = pd.Categorical(self.values, self.categories)
4950

5051
def time_regular(self):
5152
pd.Categorical(self.values, self.categories)
@@ -68,6 +69,9 @@ def time_all_nan(self):
6869
def time_from_codes_all_int8(self):
6970
pd.Categorical.from_codes(self.values_all_int8, self.categories)
7071

72+
def time_existing_categorical(self):
73+
pd.Categorical(self.categorical)
74+
7175

7276
class ValueCounts(object):
7377

pandas/core/arrays/categorical.py

+10
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,16 @@ class Categorical(ExtensionArray, PandasObject):
314314
def __init__(self, values, categories=None, ordered=None, dtype=None,
315315
fastpath=False):
316316

317+
# GH23814, for perf, if no optional params used and values already an
318+
# instance of Categorical, simply return the same dtype/codes
319+
if categories is None and ordered is None and dtype is None:
320+
if isinstance(values, (ABCSeries, ABCIndexClass)):
321+
values = values._values
322+
if isinstance(values, type(self)):
323+
self._dtype = values.dtype
324+
self._codes = values.codes.copy()
325+
return
326+
317327
# Ways of specifying the dtype (prioritized ordered)
318328
# 1. dtype is a CategoricalDtype
319329
# a.) with known categories, use dtype.categories

0 commit comments

Comments
 (0)