From e2882d0fc46114a50b1b0fc7bf35e84697194b23 Mon Sep 17 00:00:00 2001 From: Quang Nguyen Date: Mon, 13 Nov 2023 15:14:52 +0700 Subject: [PATCH 1/3] fix and add test --- pandas/core/reshape/pivot.py | 7 +++++-- pandas/tests/reshape/test_pivot.py | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/pandas/core/reshape/pivot.py b/pandas/core/reshape/pivot.py index 79354fdd12a2d..ec9d9549d4409 100644 --- a/pandas/core/reshape/pivot.py +++ b/pandas/core/reshape/pivot.py @@ -422,8 +422,11 @@ def _all_key(key): row_margin = row_margin.stack(future_stack=True) # slight hack - new_order = [len(cols)] + list(range(len(cols))) - row_margin.index = row_margin.index.reorder_levels(new_order) + new_order_indices = [len(cols)] + list(range(len(cols))) + + # GH#26568. Use names instead of indices in case of numeric names + new_order_names = [row_margin.index.names[i] for i in new_order_indices] + row_margin.index = row_margin.index.reorder_levels(new_order_names) else: row_margin = data._constructor_sliced(np.nan, index=result.columns) diff --git a/pandas/tests/reshape/test_pivot.py b/pandas/tests/reshape/test_pivot.py index aecdf0a9c6975..331bab175ec1c 100644 --- a/pandas/tests/reshape/test_pivot.py +++ b/pandas/tests/reshape/test_pivot.py @@ -2664,3 +2664,18 @@ def test_pivot_table_handles_explicit_datetime_types(self): names=["a", "date"], ) tm.assert_index_equal(pivot.index, expected) + + def test_pivot_table_with_margins_and_numeric_column_names(self): + # GH#26568 + df = DataFrame([["a", "x", 1], ["a", "y", 2], ["b", "y", 3], ["b", "z", 4]]) + + result = df.pivot_table( + index=0, columns=1, values=2, aggfunc="sum", fill_value=0, margins=True + ) + + expected = DataFrame( + [[1, 2, 0, 3], [0, 3, 4, 7], [1, 5, 4, 10]], + columns=Index(["x", "y", "z", "All"], name=1), + index=Index(["a", "b", "All"], name=0), + ) + tm.assert_frame_equal(result, expected) From 680d4c4b9e1bb241668a3fb5563af83c8d3e8692 Mon Sep 17 00:00:00 2001 From: Quang Nguyen Date: Mon, 13 Nov 2023 15:20:02 +0700 Subject: [PATCH 2/3] add whatsnew --- doc/source/whatsnew/v2.2.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v2.2.0.rst b/doc/source/whatsnew/v2.2.0.rst index efa4a52993a90..1cb9e4295a67c 100644 --- a/doc/source/whatsnew/v2.2.0.rst +++ b/doc/source/whatsnew/v2.2.0.rst @@ -441,7 +441,7 @@ Reshaping - Bug in :func:`merge_asof` raising ``TypeError`` when ``by`` dtype is not ``object``, ``int64``, or ``uint64`` (:issue:`22794`) - Bug in :func:`merge` returning columns in incorrect order when left and/or right is empty (:issue:`51929`) - Bug in :meth:`pandas.DataFrame.melt` where it would not preserve the datetime (:issue:`55254`) -- +- Bug in :meth:`pandas.DataFrame.pivot_table` where the row margin is incorrect when the columns have numeric names (:issue:`26568`) Sparse ^^^^^^ From 42fd755d19d7469096d43090a614a718245757ed Mon Sep 17 00:00:00 2001 From: Quang Nguyen Date: Tue, 14 Nov 2023 07:23:42 +0700 Subject: [PATCH 3/3] rm comment --- pandas/core/reshape/pivot.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pandas/core/reshape/pivot.py b/pandas/core/reshape/pivot.py index ec9d9549d4409..c39fbfe6b6d33 100644 --- a/pandas/core/reshape/pivot.py +++ b/pandas/core/reshape/pivot.py @@ -421,10 +421,8 @@ def _all_key(key): row_margin = data[cols + values].groupby(cols, observed=observed).agg(aggfunc) row_margin = row_margin.stack(future_stack=True) - # slight hack - new_order_indices = [len(cols)] + list(range(len(cols))) - # GH#26568. Use names instead of indices in case of numeric names + new_order_indices = [len(cols)] + list(range(len(cols))) new_order_names = [row_margin.index.names[i] for i in new_order_indices] row_margin.index = row_margin.index.reorder_levels(new_order_names) else: