diff --git a/doc/source/whatsnew/v1.5.0.rst b/doc/source/whatsnew/v1.5.0.rst index bdf811f6a8f6a..c54730a78ad36 100644 --- a/doc/source/whatsnew/v1.5.0.rst +++ b/doc/source/whatsnew/v1.5.0.rst @@ -1027,6 +1027,7 @@ Reshaping - Bug in :func:`concat` losing dtype of columns when ``join="outer"`` and ``sort=True`` (:issue:`47329`) - Bug in :func:`concat` not sorting the column names when ``None`` is included (:issue:`47331`) - Bug in :func:`concat` with identical key leads to error when indexing :class:`MultiIndex` (:issue:`46519`) +- Bug in :func:`pivot_table` raising ``TypeError`` when ``dropna=True`` and aggregation column has extension array dtype (:issue:`47477`) - Bug in :meth:`DataFrame.join` with a list when using suffixes to join DataFrames with duplicate column names (:issue:`46396`) - Bug in :meth:`DataFrame.pivot_table` with ``sort=False`` results in sorted index (:issue:`17041`) - Bug in :meth:`concat` when ``axis=1`` and ``sort=False`` where the resulting Index was a :class:`Int64Index` instead of a :class:`RangeIndex` (:issue:`46675`) diff --git a/pandas/core/reshape/pivot.py b/pandas/core/reshape/pivot.py index 5226c928c6f73..867835ef7f0a3 100644 --- a/pandas/core/reshape/pivot.py +++ b/pandas/core/reshape/pivot.py @@ -178,7 +178,9 @@ def __internal_pivot_table( and v in agged and not is_integer_dtype(agged[v]) ): - if not isinstance(agged[v], ABCDataFrame): + if not isinstance(agged[v], ABCDataFrame) and isinstance( + data[v].dtype, np.dtype + ): # exclude DataFrame case bc maybe_downcast_to_dtype expects # ArrayLike # e.g. test_pivot_table_multiindex_columns_doctest_case diff --git a/pandas/tests/reshape/test_pivot.py b/pandas/tests/reshape/test_pivot.py index 8312e3b9de9a7..e2eed4358aaaa 100644 --- a/pandas/tests/reshape/test_pivot.py +++ b/pandas/tests/reshape/test_pivot.py @@ -2223,6 +2223,21 @@ def test_pivot_table_with_margins_and_numeric_columns(self): tm.assert_frame_equal(result, expected) + @pytest.mark.parametrize("dropna", [True, False]) + def test_pivot_ea_dtype_dropna(self, dropna): + # GH#47477 + df = DataFrame({"x": "a", "y": "b", "age": Series([20, 40], dtype="Int64")}) + result = df.pivot_table( + index="x", columns="y", values="age", aggfunc="mean", dropna=dropna + ) + expected = DataFrame( + [[30]], + index=Index(["a"], name="x"), + columns=Index(["b"], name="y"), + dtype="Float64", + ) + tm.assert_frame_equal(result, expected) + class TestPivot: def test_pivot(self):