diff --git a/doc/source/whatsnew/v2.0.2.rst b/doc/source/whatsnew/v2.0.2.rst index 0d6647dc38b3c..c8159be4d7b6b 100644 --- a/doc/source/whatsnew/v2.0.2.rst +++ b/doc/source/whatsnew/v2.0.2.rst @@ -13,6 +13,7 @@ including other versions of pandas. Fixed regressions ~~~~~~~~~~~~~~~~~ +- Fixed performance regression in :meth:`GroupBy.apply` (:issue:`53195`) - Fixed regression in :func:`read_sql` dropping columns with duplicated column names (:issue:`53117`) - Fixed regression in :meth:`DataFrame.loc` losing :class:`MultiIndex` name when enlarging object (:issue:`53053`) - Fixed regression in :meth:`DataFrame.to_string` printing a backslash at the end of the first row of data, instead of headers, when the DataFrame doesn't fit the line width (:issue:`53054`) diff --git a/pandas/core/reshape/concat.py b/pandas/core/reshape/concat.py index 018075c1687fe..23fd93aca4258 100644 --- a/pandas/core/reshape/concat.py +++ b/pandas/core/reshape/concat.py @@ -532,7 +532,7 @@ def _clean_keys_and_objs( keys = type(keys).from_tuples(clean_keys, names=keys.names) else: name = getattr(keys, "name", None) - keys = Index(clean_keys, name=name) + keys = Index(clean_keys, name=name, dtype=getattr(keys, "dtype", None)) if len(objs) == 0: raise ValueError("All objects passed were None") @@ -806,15 +806,19 @@ def _make_concat_multiindex(indexes, keys, levels=None, names=None) -> MultiInde for hlevel, level in zip(zipped, levels): to_concat = [] - for key, index in zip(hlevel, indexes): - # Find matching codes, include matching nan values as equal. - mask = (isna(level) & isna(key)) | (level == key) - if not mask.any(): - raise ValueError(f"Key {key} not in level {level}") - i = np.nonzero(mask)[0][0] - - to_concat.append(np.repeat(i, len(index))) - codes_list.append(np.concatenate(to_concat)) + if isinstance(hlevel, Index) and hlevel.equals(level): + lens = [len(idx) for idx in indexes] + codes_list.append(np.repeat(np.arange(len(hlevel)), lens)) + else: + for key, index in zip(hlevel, indexes): + # Find matching codes, include matching nan values as equal. + mask = (isna(level) & isna(key)) | (level == key) + if not mask.any(): + raise ValueError(f"Key {key} not in level {level}") + i = np.nonzero(mask)[0][0] + + to_concat.append(np.repeat(i, len(index))) + codes_list.append(np.concatenate(to_concat)) concat_index = _concat_indexes(indexes)