diff --git a/pandas/core/dtypes/cast.py b/pandas/core/dtypes/cast.py index 06e71c18c55cc..0917cf1787d5b 100644 --- a/pandas/core/dtypes/cast.py +++ b/pandas/core/dtypes/cast.py @@ -94,6 +94,7 @@ PeriodDtype, ) from pandas.core.dtypes.generic import ( + ABCDataFrame, ABCExtensionArray, ABCSeries, ) @@ -238,6 +239,9 @@ def maybe_downcast_to_dtype( try to cast to the specified dtype (e.g. convert back to bool/int or could be an astype of float64->float32 """ + if isinstance(result, ABCDataFrame): + # see test_pivot_table_doctest_case + return result do_round = False if isinstance(dtype, str): @@ -307,7 +311,7 @@ def maybe_downcast_numeric( ------- ndarray or ExtensionArray """ - if not isinstance(dtype, np.dtype): + if not isinstance(dtype, np.dtype) or not isinstance(result.dtype, np.dtype): # e.g. SparseDtype has no itemsize attr return result diff --git a/pandas/tests/io/parser/common/test_chunksize.py b/pandas/tests/io/parser/common/test_chunksize.py index 8e1e9fb6e458f..4bc3f3c38f506 100644 --- a/pandas/tests/io/parser/common/test_chunksize.py +++ b/pandas/tests/io/parser/common/test_chunksize.py @@ -193,7 +193,7 @@ def test_warn_if_chunks_have_mismatched_type(all_parsers, request): # 2021-02-21 this occasionally fails on the CI with an unexpected # ResourceWarning that we have been unable to track down, # see GH#38630 - if "ResourceError" not in str(err) or parser.engine != "python": + if "ResourceWarning" not in str(err) or parser.engine != "python": raise # Check the main assertion of the test before re-raising diff --git a/pandas/tests/reshape/test_pivot.py b/pandas/tests/reshape/test_pivot.py index 8d2b4f2b325c2..131fb14d0bf85 100644 --- a/pandas/tests/reshape/test_pivot.py +++ b/pandas/tests/reshape/test_pivot.py @@ -2063,6 +2063,55 @@ def agg(arr): with pytest.raises(KeyError, match="notpresent"): foo.pivot_table("notpresent", "X", "Y", aggfunc=agg) + def test_pivot_table_doctest_case(self): + # TODO: better name. the relevant characteristic is that + # the call to maybe_downcast_to_dtype(agged[v], data[v].dtype) in + # __internal_pivot_table has `agged[v]` a DataFrame instead of Series, + # i.e agged.columns is not unique + df = DataFrame( + { + "A": ["foo", "foo", "foo", "foo", "foo", "bar", "bar", "bar", "bar"], + "B": ["one", "one", "one", "two", "two", "one", "one", "two", "two"], + "C": [ + "small", + "large", + "large", + "small", + "small", + "large", + "small", + "small", + "large", + ], + "D": [1, 2, 2, 3, 3, 4, 5, 6, 7], + "E": [2, 4, 5, 5, 6, 6, 8, 9, 9], + } + ) + + table = pivot_table( + df, + values=["D", "E"], + index=["A", "C"], + aggfunc={"D": np.mean, "E": [min, max, np.mean]}, + ) + cols = MultiIndex.from_tuples( + [("D", "mean"), ("E", "max"), ("E", "mean"), ("E", "min")] + ) + index = MultiIndex.from_tuples( + [("bar", "large"), ("bar", "small"), ("foo", "large"), ("foo", "small")], + names=["A", "C"], + ) + vals = np.array( + [ + [5.5, 9.0, 7.5, 6.0], + [5.5, 9.0, 8.5, 8.0], + [2.0, 5.0, 4.5, 4.0], + [2.33333333, 6.0, 4.33333333, 2.0], + ] + ) + expected = DataFrame(vals, columns=cols, index=index) + tm.assert_frame_equal(table, expected) + class TestPivot: def test_pivot(self):