Skip to content

Commit

Permalink
BUG: fixed to_numeric loss in precision when converting decimal type …
Browse files Browse the repository at this point in the history
…to integer pandas-dev#57213
  • Loading branch information
Leventide committed Apr 3, 2024
1 parent 9cd5e55 commit 17fe351
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 1 deletion.
1 change: 1 addition & 0 deletions doc/source/whatsnew/v3.0.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@ Performance improvements
Bug fixes
~~~~~~~~~
- Fixed bug in :class:`SparseDtype` for equal comparison with na fill value. (:issue:`54770`)
- Fixed bug in :func:`to_numeric` that resulted in precision loss when converting decimal type to integer. (:issue:`57213`)
- Fixed bug in :meth:`.DataFrameGroupBy.median` where nat values gave an incorrect result. (:issue:`57926`)
- Fixed bug in :meth:`DataFrame.cumsum` which was raising ``IndexError`` if dtype is ``timedelta64[ns]`` (:issue:`57956`)
- Fixed bug in :meth:`DataFrame.join` inconsistently setting result index name (:issue:`55815`)
Expand Down
13 changes: 12 additions & 1 deletion pandas/core/tools/numeric.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from __future__ import annotations

from decimal import Decimal
from typing import (
TYPE_CHECKING,
Literal,
Expand Down Expand Up @@ -209,6 +210,7 @@ def to_numeric(
values = values.view(np.int64)
else:
values = ensure_object(values)
old_values = values
coerce_numeric = errors != "raise"
values, new_mask = lib.maybe_convert_numeric( # type: ignore[call-overload]
values,
Expand Down Expand Up @@ -255,7 +257,16 @@ def to_numeric(
for typecode in typecodes:
dtype = np.dtype(typecode)
if dtype.itemsize <= values.dtype.itemsize:
values = maybe_downcast_numeric(values, dtype)
try:
if (len(old_values) != 0) and isinstance(
old_values[0], Decimal
):
if dtype.itemsize == values.dtype.itemsize:
values = np.array(old_values, dtype=dtype)
else:
values = maybe_downcast_numeric(values, dtype)
except NameError:
values = maybe_downcast_numeric(values, dtype)

# successful conversion
if values.dtype == dtype:
Expand Down
7 changes: 7 additions & 0 deletions pandas/tests/tools/test_to_numeric.py
Original file line number Diff line number Diff line change
Expand Up @@ -904,3 +904,10 @@ def test_coerce_pyarrow_backend():
result = to_numeric(ser, errors="coerce", dtype_backend="pyarrow")
expected = Series([1, 2, None], dtype=ArrowDtype(pa.int64()))
tm.assert_series_equal(result, expected)


def test_decimal_precision():
df = DataFrame({"column1": [decimal.Decimal("1" * 19)]})
result = to_numeric(df["column1"], downcast="integer")
expected = df["column1"].astype("int64")
tm.assert_series_equal(result, expected)

0 comments on commit 17fe351

Please sign in to comment.