diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 8f65277f660f7..dea246bcd1cf8 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -9347,8 +9347,12 @@ def pivot( on the rows and columns. dropna : bool, default True Do not include columns whose entries are all NaN. If True, - rows with a NaN value in any column will be omitted before - computing margins. + + * rows with an NA value in any column will be omitted before computing + margins, + * index/column keys containing NA values will be dropped (see ``dropna`` + parameter in :meth:`DataFrame.groupby`). + margins_name : str, default 'All' Name of the row / column that will contain the totals when margins is True. diff --git a/pandas/core/reshape/pivot.py b/pandas/core/reshape/pivot.py index cfc6f91557781..0a8ade581dea0 100644 --- a/pandas/core/reshape/pivot.py +++ b/pandas/core/reshape/pivot.py @@ -102,8 +102,11 @@ def pivot_table( on the rows and columns. dropna : bool, default True Do not include columns whose entries are all NaN. If True, - rows with a NaN value in any column will be omitted before - computing margins. + + * rows with an NA value in any column will be omitted before computing margins, + * index/column keys containing NA values will be dropped (see ``dropna`` + parameter in :meth:``DataFrame.groupby``). + margins_name : str, default 'All' Name of the row / column that will contain the totals when margins is True. diff --git a/pandas/tests/reshape/test_pivot.py b/pandas/tests/reshape/test_pivot.py index 374d236c8ff39..46eee13755b2d 100644 --- a/pandas/tests/reshape/test_pivot.py +++ b/pandas/tests/reshape/test_pivot.py @@ -2529,6 +2529,30 @@ def test_pivot_table_aggfunc_nunique_with_different_values(self): tm.assert_frame_equal(result, expected) + def test_pivot_table_index_and_column_keys_with_nan(self, dropna): + # GH#61113 + data = {"row": [None, *range(4)], "col": [*range(4), None], "val": range(5)} + df = DataFrame(data) + result = df.pivot_table(values="val", index="row", columns="col", dropna=dropna) + e_axis = [*range(4), None] + nan = np.nan + e_data = [ + [nan, 1.0, nan, nan, nan], + [nan, nan, 2.0, nan, nan], + [nan, nan, nan, 3.0, nan], + [nan, nan, nan, nan, 4.0], + [0.0, nan, nan, nan, nan], + ] + expected = DataFrame( + data=e_data, + index=Index(data=e_axis, name="row"), + columns=Index(data=e_axis, name="col"), + ) + if dropna: + expected = expected.loc[[0, 1, 2], [1, 2, 3]] + + tm.assert_frame_equal(left=result, right=expected) + class TestPivot: def test_pivot(self):