diff --git a/pandas/core/groupby/generic.py b/pandas/core/groupby/generic.py index 499bef2b61046..3dfad7f172cda 100644 --- a/pandas/core/groupby/generic.py +++ b/pandas/core/groupby/generic.py @@ -15,7 +15,6 @@ Any, Callable, Hashable, - Iterable, Literal, Mapping, NamedTuple, @@ -1337,38 +1336,27 @@ def _python_agg_general(self, func, *args, **kwargs): func = com.is_builtin_func(func) f = lambda x: func(x, *args, **kwargs) - # iterate through "columns" ex exclusions to populate output dict - output: dict[base.OutputKey, ArrayLike] = {} - if self.ngroups == 0: # e.g. test_evaluate_with_empty_groups different path gets different # result dtype in empty case. return self._python_apply_general(f, self._selected_obj, is_agg=True) - for idx, obj in enumerate(self._iterate_slices()): - name = obj.name - result = self.grouper.agg_series(obj, f) - key = base.OutputKey(label=name, position=idx) - output[key] = result + obj = self._obj_with_exclusions + if self.axis == 1: + obj = obj.T - if not output: + if not len(obj.columns): # e.g. test_margins_no_values_no_cols return self._python_apply_general(f, self._selected_obj) - res = self._indexed_output_to_ndframe(output) - return self._wrap_aggregated_output(res) - - def _iterate_slices(self) -> Iterable[Series]: - obj = self._obj_with_exclusions - if self.axis == 1: - obj = obj.T + output: dict[int, ArrayLike] = {} + for idx, (name, ser) in enumerate(obj.items()): + result = self.grouper.agg_series(ser, f) + output[idx] = result - if isinstance(obj, Series): - # Occurs when doing DataFrameGroupBy(...)["X"] - yield obj - else: - for label, values in obj.items(): - yield values + res = self.obj._constructor(output) + res.columns = obj.columns.copy(deep=False) + return self._wrap_aggregated_output(res) def _aggregate_frame(self, func, *args, **kwargs) -> DataFrame: if self.grouper.nkeys != 1: @@ -1830,20 +1818,6 @@ def _get_data_to_aggregate( mgr = mgr.get_numeric_data(copy=False) return mgr - def _indexed_output_to_ndframe( - self, output: Mapping[base.OutputKey, ArrayLike] - ) -> DataFrame: - """ - Wrap the dict result of a GroupBy aggregation into a DataFrame. - """ - indexed_output = {key.position: val for key, val in output.items()} - columns = Index([key.label for key in output]) - columns._set_names(self._obj_with_exclusions._get_axis(1 - self.axis).names) - - result = self.obj._constructor(indexed_output) - result.columns = columns - return result - def _wrap_agged_manager(self, mgr: Manager2D) -> DataFrame: return self.obj._constructor(mgr) diff --git a/pandas/core/groupby/groupby.py b/pandas/core/groupby/groupby.py index 3973dc18abd59..55e14bc11246b 100644 --- a/pandas/core/groupby/groupby.py +++ b/pandas/core/groupby/groupby.py @@ -1099,11 +1099,6 @@ def _insert_inaxis_grouper(self, result: Series | DataFrame) -> DataFrame: return result - def _indexed_output_to_ndframe( - self, result: Mapping[base.OutputKey, ArrayLike] - ) -> Series | DataFrame: - raise AbstractMethodError(self) - @final def _maybe_transpose_result(self, result: NDFrameT) -> NDFrameT: if self.axis == 1: