Skip to content

Commit 2e5c28f

Browse files
authored
BUG/TST: Calling __finalize__ in pivot_table, groupby.median and groupby.mean (#39473)
1 parent 6d2c2e1 commit 2e5c28f

File tree

4 files changed

+62
-14
lines changed

4 files changed

+62
-14
lines changed

doc/source/whatsnew/v1.3.0.rst

+2
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,8 @@ Groupby/resample/rolling
434434
- Bug in :meth:`Series.resample` would raise when the index was a :class:`PeriodIndex` consisting of ``NaT`` (:issue:`39227`)
435435
- Bug in :meth:`core.window.rolling.RollingGroupby.corr` and :meth:`core.window.expanding.ExpandingGroupby.corr` where the groupby column would return 0 instead of ``np.nan`` when providing ``other`` that was longer than each group (:issue:`39591`)
436436
- Bug in :meth:`core.window.expanding.ExpandingGroupby.corr` and :meth:`core.window.expanding.ExpandingGroupby.cov` where 1 would be returned instead of ``np.nan`` when providing ``other`` that was longer than each group (:issue:`39591`)
437+
- Bug in :meth:`.GroupBy.mean`, :meth:`.GroupBy.median` and :meth:`DataFrame.pivot_table` not propagating metadata (:issue:`28283`)
438+
-
437439

438440
Reshaping
439441
^^^^^^^^^

pandas/core/groupby/groupby.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -1546,11 +1546,12 @@ def mean(self, numeric_only: bool = True):
15461546
2 4.0
15471547
Name: B, dtype: float64
15481548
"""
1549-
return self._cython_agg_general(
1549+
result = self._cython_agg_general(
15501550
"mean",
15511551
alt=lambda x, axis: Series(x).mean(numeric_only=numeric_only),
15521552
numeric_only=numeric_only,
15531553
)
1554+
return result.__finalize__(self.obj, method="groupby")
15541555

15551556
@final
15561557
@Substitution(name="groupby")
@@ -1572,11 +1573,12 @@ def median(self, numeric_only=True):
15721573
Series or DataFrame
15731574
Median of values within each group.
15741575
"""
1575-
return self._cython_agg_general(
1576+
result = self._cython_agg_general(
15761577
"median",
15771578
alt=lambda x, axis: Series(x).median(axis=axis, numeric_only=numeric_only),
15781579
numeric_only=numeric_only,
15791580
)
1581+
return result.__finalize__(self.obj, method="groupby")
15801582

15811583
@final
15821584
@Substitution(name="groupby")

pandas/core/reshape/pivot.py

+39-5
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
import numpy as np
1818

1919
from pandas._typing import (
20+
AggFuncType,
21+
AggFuncTypeBase,
22+
AggFuncTypeDict,
2023
FrameOrSeriesUnion,
2124
IndexLabel,
2225
)
@@ -57,11 +60,11 @@
5760
@Substitution("\ndata : DataFrame")
5861
@Appender(_shared_docs["pivot_table"], indents=1)
5962
def pivot_table(
60-
data,
63+
data: DataFrame,
6164
values=None,
6265
index=None,
6366
columns=None,
64-
aggfunc="mean",
67+
aggfunc: AggFuncType = "mean",
6568
fill_value=None,
6669
margins=False,
6770
dropna=True,
@@ -75,7 +78,7 @@ def pivot_table(
7578
pieces: List[DataFrame] = []
7679
keys = []
7780
for func in aggfunc:
78-
table = pivot_table(
81+
_table = __internal_pivot_table(
7982
data,
8083
values=values,
8184
index=index,
@@ -87,11 +90,42 @@ def pivot_table(
8790
margins_name=margins_name,
8891
observed=observed,
8992
)
90-
pieces.append(table)
93+
pieces.append(_table)
9194
keys.append(getattr(func, "__name__", func))
9295

93-
return concat(pieces, keys=keys, axis=1)
96+
table = concat(pieces, keys=keys, axis=1)
97+
return table.__finalize__(data, method="pivot_table")
98+
99+
table = __internal_pivot_table(
100+
data,
101+
values,
102+
index,
103+
columns,
104+
aggfunc,
105+
fill_value,
106+
margins,
107+
dropna,
108+
margins_name,
109+
observed,
110+
)
111+
return table.__finalize__(data, method="pivot_table")
112+
94113

114+
def __internal_pivot_table(
115+
data: DataFrame,
116+
values,
117+
index,
118+
columns,
119+
aggfunc: Union[AggFuncTypeBase, AggFuncTypeDict],
120+
fill_value,
121+
margins: bool,
122+
dropna: bool,
123+
margins_name: str,
124+
observed: bool,
125+
) -> DataFrame:
126+
"""
127+
Helper of :func:`pandas.pivot_table` for any non-list ``aggfunc``.
128+
"""
95129
keys = index + columns
96130

97131
values_passed = values is not None

pandas/tests/generic/test_finalize.py

+17-7
Original file line numberDiff line numberDiff line change
@@ -149,13 +149,15 @@
149149
marks=not_implemented_mark,
150150
),
151151
(pd.DataFrame, frame_data, operator.methodcaller("pivot", columns="A")),
152-
pytest.param(
153-
(
154-
pd.DataFrame,
155-
{"A": [1], "B": [1]},
156-
operator.methodcaller("pivot_table", columns="A"),
157-
),
158-
marks=not_implemented_mark,
152+
(
153+
pd.DataFrame,
154+
({"A": [1], "B": [1]},),
155+
operator.methodcaller("pivot_table", columns="A"),
156+
),
157+
(
158+
pd.DataFrame,
159+
({"A": [1], "B": [1]},),
160+
operator.methodcaller("pivot_table", columns="A", aggfunc=["mean", "sum"]),
159161
),
160162
(pd.DataFrame, frame_data, operator.methodcaller("stack")),
161163
pytest.param(
@@ -740,6 +742,8 @@ def test_categorical_accessor(method):
740742
[
741743
operator.methodcaller("sum"),
742744
lambda x: x.agg("sum"),
745+
lambda x: x.agg("mean"),
746+
lambda x: x.agg("median"),
743747
],
744748
)
745749
def test_groupby_finalize(obj, method):
@@ -757,6 +761,12 @@ def test_groupby_finalize(obj, method):
757761
lambda x: x.agg(["sum", "count"]),
758762
lambda x: x.transform(lambda y: y),
759763
lambda x: x.apply(lambda y: y),
764+
lambda x: x.agg("std"),
765+
lambda x: x.agg("var"),
766+
lambda x: x.agg("sem"),
767+
lambda x: x.agg("size"),
768+
lambda x: x.agg("ohlc"),
769+
lambda x: x.agg("describe"),
760770
],
761771
)
762772
@not_implemented_mark

0 commit comments

Comments
 (0)