From a55e4c5014ab18abf403262047f0b3f0ec3ee6a0 Mon Sep 17 00:00:00 2001 From: Mabel Villalba Date: Sat, 23 Nov 2019 23:43:52 +0100 Subject: [PATCH] BUG: pivot_table not returning correct type when margin=True and aggfunc='mean' (#28248) --- doc/source/whatsnew/v1.0.0.rst | 2 ++ pandas/core/reshape/pivot.py | 5 ++++- pandas/tests/reshape/merge/test_pivot_old.py | 0 pandas/tests/reshape/test_pivot.py | 18 ++++++++++++++++++ 4 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 pandas/tests/reshape/merge/test_pivot_old.py diff --git a/doc/source/whatsnew/v1.0.0.rst b/doc/source/whatsnew/v1.0.0.rst index 2b68ddf3d8918e..28a61c535f951b 100644 --- a/doc/source/whatsnew/v1.0.0.rst +++ b/doc/source/whatsnew/v1.0.0.rst @@ -595,6 +595,7 @@ Reshaping - Bug in :meth:`DataFrame.apply` that caused incorrect output with empty :class:`DataFrame` (:issue:`28202`, :issue:`21959`) - Bug in :meth:`DataFrame.stack` not handling non-unique indexes correctly when creating MultiIndex (:issue: `28301`) +- Bug in :meth:`pivot_table` not returning correct type ``float`` when ``margins=True`` and ``aggfunc='mean'`` (:issue:`24893`) - Bug :func:`merge_asof` could not use :class:`datetime.timedelta` for ``tolerance`` kwarg (:issue:`28098`) - Bug in :func:`merge`, did not append suffixes correctly with MultiIndex (:issue:`28518`) - :func:`qcut` and :func:`cut` now handle boolean input (:issue:`20303`) @@ -604,6 +605,7 @@ Reshaping - Bug where :meth:`DataFrame.equals` returned True incorrectly in some cases when two DataFrames had the same columns in different orders (:issue:`28839`) - Bug in :meth:`DataFrame.replace` that caused non-numeric replacer's dtype not respected (:issue:`26632`) + Sparse ^^^^^^ - Bug in :class:`SparseDataFrame` arithmetic operations incorrectly casting inputs to float (:issue:`28107`) diff --git a/pandas/core/reshape/pivot.py b/pandas/core/reshape/pivot.py index c7d3adece521e8..27d6a28a33cc67 100644 --- a/pandas/core/reshape/pivot.py +++ b/pandas/core/reshape/pivot.py @@ -261,9 +261,12 @@ def _add_margins( row_names = result.index.names try: + # check the result column and leave floats for dtype in set(result.dtypes): cols = result.select_dtypes([dtype]).columns - margin_dummy[cols] = margin_dummy[cols].astype(dtype) + margin_dummy[cols] = margin_dummy[cols].apply( + maybe_downcast_to_dtype, args=(dtype,) + ) result = result.append(margin_dummy) except TypeError: diff --git a/pandas/tests/reshape/merge/test_pivot_old.py b/pandas/tests/reshape/merge/test_pivot_old.py new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/pandas/tests/reshape/test_pivot.py b/pandas/tests/reshape/test_pivot.py index 5b6dc70894857b..bd1d3d2d5bb63d 100644 --- a/pandas/tests/reshape/test_pivot.py +++ b/pandas/tests/reshape/test_pivot.py @@ -1656,6 +1656,24 @@ def test_categorical_margins_category(self, observed): table = df.pivot_table("x", "y", "z", dropna=observed, margins=True) tm.assert_frame_equal(table, expected) + def test_margins_casted_to_float(self, observed): + # GH 24893 + df = pd.DataFrame( + { + "A": [2, 4, 6, 8], + "B": [1, 4, 5, 8], + "C": [1, 3, 4, 6], + "D": ["X", "X", "Y", "Y"], + } + ) + + result = pd.pivot_table(df, index="D", margins=True) + expected = pd.DataFrame( + {"A": [3, 7, 5], "B": [2.5, 6.5, 4.5], "C": [2, 5, 3.5]}, + index=pd.Index(["X", "Y", "All"], name="D"), + ) + tm.assert_frame_equal(result, expected) + def test_pivot_with_categorical(self, observed, ordered_fixture): # gh-21370 idx = [np.nan, "low", "high", "low", np.nan]