From 0f3b2b3d14821c6568762b212b7dd0f9323506e6 Mon Sep 17 00:00:00 2001 From: Brock Date: Mon, 26 Jun 2023 15:25:05 -0700 Subject: [PATCH] REF: simplify _from_mgr constructors, use in more places --- pandas/core/frame.py | 29 ++++++++++++++++------------- pandas/core/generic.py | 4 ++-- pandas/core/groupby/groupby.py | 6 +++--- pandas/core/reshape/concat.py | 3 ++- pandas/core/series.py | 24 ++++++++++++++---------- 5 files changed, 37 insertions(+), 29 deletions(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index c7e8f74ff7849..2225312742744 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -638,12 +638,14 @@ def _constructor(self) -> Callable[..., DataFrame]: return DataFrame def _constructor_from_mgr(self, mgr, axes): - if self._constructor is DataFrame: - # we are pandas.DataFrame (or a subclass that doesn't override _constructor) - return self._from_mgr(mgr, axes=axes) + df = self._from_mgr(mgr, axes=axes) + + if type(self) is DataFrame: + # fastpath avoiding constructor call + return df else: assert axes is mgr.axes - return self._constructor(mgr) + return self._constructor(df, copy=False) _constructor_sliced: Callable[..., Series] = Series @@ -651,10 +653,13 @@ def _sliced_from_mgr(self, mgr, axes) -> Series: return Series._from_mgr(mgr, axes) def _constructor_sliced_from_mgr(self, mgr, axes): - if self._constructor_sliced is Series: - return self._sliced_from_mgr(mgr, axes) + ser = self._sliced_from_mgr(mgr, axes=axes) + ser._name = None # caller is responsible for setting real name + if type(self) is DataFrame: + # fastpath avoiding constructor call + return ser assert axes is mgr.axes - return self._constructor_sliced(mgr) + return self._constructor_sliced(ser, copy=False) # ---------------------------------------------------------------------- # Constructors @@ -11763,12 +11768,10 @@ def isin_(x): ) return result.reshape(x.shape) - res_values = self._mgr.apply(isin_) - result = self._constructor( - res_values, - self.index, - self.columns, - copy=False, + res_mgr = self._mgr.apply(isin_) + result = self._constructor_from_mgr( + res_mgr, + axes=res_mgr.axes, ) return result.__finalize__(self, method="isin") diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 033265b1f373e..1a2c9ea2d7300 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -319,7 +319,7 @@ def _as_manager(self, typ: str, copy: bool_t = True) -> Self: new_mgr: Manager new_mgr = mgr_to_mgr(self._mgr, typ=typ, copy=copy) # fastpath of passing a manager doesn't check the option/manager class - return self._constructor(new_mgr).__finalize__(self) + return self._constructor_from_mgr(new_mgr, axes=new_mgr.axes).__finalize__(self) @classmethod def _from_mgr(cls, mgr: Manager, axes: list[Index]) -> Self: @@ -6919,7 +6919,7 @@ def _fillna_with_method( inplace=inplace, downcast=downcast, ) - result = self._constructor(new_mgr) + result = self._constructor_from_mgr(new_mgr, axes=new_mgr.axes) if inplace: return self._update_inplace(result) else: diff --git a/pandas/core/groupby/groupby.py b/pandas/core/groupby/groupby.py index c094a62b22feb..1a17fef071a2f 100644 --- a/pandas/core/groupby/groupby.py +++ b/pandas/core/groupby/groupby.py @@ -1519,11 +1519,11 @@ def _numba_agg_general( aggregator = executor.generate_shared_aggregator( func, dtype_mapping, **get_jit_arguments(engine_kwargs) ) - result = sorted_df._mgr.apply( + res_mgr = sorted_df._mgr.apply( aggregator, start=starts, end=ends, **aggregator_kwargs ) - result.axes[1] = self.grouper.result_index - result = df._constructor(result) + res_mgr.axes[1] = self.grouper.result_index + result = df._constructor_from_mgr(res_mgr, axes=res_mgr.axes) if data.ndim == 1: result = result.squeeze("columns") diff --git a/pandas/core/reshape/concat.py b/pandas/core/reshape/concat.py index 4994ed347629e..81e3f575f6cb3 100644 --- a/pandas/core/reshape/concat.py +++ b/pandas/core/reshape/concat.py @@ -640,7 +640,8 @@ def get_result(self): mgr = type(sample._mgr).from_array(res, index=new_index) - result = cons(mgr, name=name, fastpath=True) + result = sample._constructor_from_mgr(mgr, axes=mgr.axes) + result._name = name return result.__finalize__(self, method="concat") # combine as columns in a frame diff --git a/pandas/core/series.py b/pandas/core/series.py index 798c19db7079d..8785e2fb65fb8 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -575,12 +575,14 @@ def _constructor(self) -> Callable[..., Series]: return Series def _constructor_from_mgr(self, mgr, axes): - if self._constructor is Series: - # we are pandas.Series (or a subclass that doesn't override _constructor) - return self._from_mgr(mgr, axes=axes) + ser = self._from_mgr(mgr, axes=axes) + ser._name = None # caller is responsible for setting real name + if type(self) is Series: + # fastpath avoiding constructor call + return ser else: assert axes is mgr.axes - return self._constructor(mgr) + return self._constructor(ser, copy=False) @property def _constructor_expanddim(self) -> Callable[..., DataFrame]: @@ -599,15 +601,17 @@ def _expanddim_from_mgr(self, mgr, axes) -> DataFrame: # once downstream packages (geopandas) have had a chance to implement # their own overrides. # error: "Callable[..., DataFrame]" has no attribute "_from_mgr" [attr-defined] - return self._constructor_expanddim._from_mgr( # type: ignore[attr-defined] - mgr, axes=mgr.axes - ) + from pandas import DataFrame + + return DataFrame._from_mgr(mgr, axes=mgr.axes) def _constructor_expanddim_from_mgr(self, mgr, axes): - if self._constructor is Series: - return self._expanddim_from_mgr(mgr, axes) + df = self._expanddim_from_mgr(mgr, axes) + if type(self) is Series: + # fastpath avoiding constructor + return df assert axes is mgr.axes - return self._constructor_expanddim(mgr) + return self._constructor_expanddim(df, copy=False) # types @property