From 3d9d8f6ecc58614fa1ab7579f2ed714bf85ee474 Mon Sep 17 00:00:00 2001 From: Michiel De Muynck Date: Thu, 7 Nov 2024 17:24:49 +0000 Subject: [PATCH 1/3] Fix issue 50174 --- pandas/io/excel/_base.py | 4 ++++ pandas/tests/io/excel/test_writers.py | 31 +++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/pandas/io/excel/_base.py b/pandas/io/excel/_base.py index ef52107c283e9..ced2ad91dba1e 100644 --- a/pandas/io/excel/_base.py +++ b/pandas/io/excel/_base.py @@ -8,6 +8,7 @@ Sequence, ) import datetime +from decimal import Decimal from functools import partial import os from textwrap import fill @@ -43,6 +44,7 @@ from pandas.core.dtypes.common import ( is_bool, + is_decimal, is_file_like, is_float, is_integer, @@ -1348,6 +1350,8 @@ def _value_with_fmt( val = float(val) elif is_bool(val): val = bool(val) + elif is_decimal(val): + val = Decimal(val) elif isinstance(val, datetime.datetime): fmt = self._datetime_format elif isinstance(val, datetime.date): diff --git a/pandas/tests/io/excel/test_writers.py b/pandas/tests/io/excel/test_writers.py index 44266ae9a62a5..acc4caa3cab06 100644 --- a/pandas/tests/io/excel/test_writers.py +++ b/pandas/tests/io/excel/test_writers.py @@ -3,6 +3,7 @@ datetime, timedelta, ) +from decimal import Decimal from functools import partial from io import BytesIO import os @@ -977,6 +978,36 @@ def test_to_excel_float_format(self, tmp_excel): ) tm.assert_frame_equal(result, expected) + def test_to_excel_datatypes_preserved(self, tmp_excel): + # Test that when writing and reading Excel with dtype=object, + # datatypes are preserved, except Decimals which should be + # stored as floats + + # see gh-50174 + df = DataFrame( + [ + [1.23, "1.23", Decimal("1.23")], + [4.56, "4.56", Decimal("4.56")], + ], + index=["A", "B"], + columns=["X", "Y", "Z"], + ) + df.to_excel(tmp_excel) + + with ExcelFile(tmp_excel) as reader: + result = pd.read_excel(reader, index_col=0, dtype=object) + + expected = DataFrame( + [ + [1.23, "1.23", 1.23], + [4.56, "4.56", 4.56], + ], + index=["A", "B"], + columns=["X", "Y", "Z"], + dtype=object, + ) + tm.assert_frame_equal(result, expected) + def test_to_excel_output_encoding(self, tmp_excel): # Avoid mixed inferred_type. df = DataFrame( From 023f98f1ca77baf49924a248b9a39dff0227eef0 Mon Sep 17 00:00:00 2001 From: Michiel De Muynck Date: Thu, 7 Nov 2024 17:41:29 +0000 Subject: [PATCH 2/3] Add release notes --- doc/source/whatsnew/v2.3.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v2.3.0.rst b/doc/source/whatsnew/v2.3.0.rst index 922cc0ead7fb0..29bd5f1c8187f 100644 --- a/doc/source/whatsnew/v2.3.0.rst +++ b/doc/source/whatsnew/v2.3.0.rst @@ -133,7 +133,7 @@ MultiIndex I/O ^^^ -- +- :meth:`DataFrame.to_excel` was storing decimals as strings instead of numbers (:issue:`50174`) - Period From 2af69735917930b23bf6ece953a3eb7b560a6ad5 Mon Sep 17 00:00:00 2001 From: Michiel De Muynck Date: Thu, 7 Nov 2024 17:43:43 +0000 Subject: [PATCH 3/3] Use correct github issue number --- doc/source/whatsnew/v2.3.0.rst | 2 +- pandas/tests/io/excel/test_writers.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/source/whatsnew/v2.3.0.rst b/doc/source/whatsnew/v2.3.0.rst index 29bd5f1c8187f..d57d86f4a1476 100644 --- a/doc/source/whatsnew/v2.3.0.rst +++ b/doc/source/whatsnew/v2.3.0.rst @@ -133,7 +133,7 @@ MultiIndex I/O ^^^ -- :meth:`DataFrame.to_excel` was storing decimals as strings instead of numbers (:issue:`50174`) +- :meth:`DataFrame.to_excel` was storing decimals as strings instead of numbers (:issue:`49598`) - Period diff --git a/pandas/tests/io/excel/test_writers.py b/pandas/tests/io/excel/test_writers.py index acc4caa3cab06..81aa0be24bffc 100644 --- a/pandas/tests/io/excel/test_writers.py +++ b/pandas/tests/io/excel/test_writers.py @@ -983,7 +983,7 @@ def test_to_excel_datatypes_preserved(self, tmp_excel): # datatypes are preserved, except Decimals which should be # stored as floats - # see gh-50174 + # see gh-49598 df = DataFrame( [ [1.23, "1.23", Decimal("1.23")],