Skip to content

Commit 51da47f

Browse files
Update numeric.py
1 parent 73c4fce commit 51da47f

File tree

1 file changed

+33
-9
lines changed

1 file changed

+33
-9
lines changed

pandas/core/tools/numeric.py

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import annotations
22

3+
34
from typing import (
45
TYPE_CHECKING,
56
Literal,
@@ -34,13 +35,25 @@
3435
from pandas.core.arrays import BaseMaskedArray
3536
from pandas.core.arrays.string_ import StringDtype
3637

38+
from pandas.core.dtypes.common import is_string_dtype
39+
3740
if TYPE_CHECKING:
3841
from pandas._typing import (
3942
DateTimeErrorChoices,
4043
DtypeBackend,
4144
npt,
4245
)
4346

47+
def parse_numeric(value):
48+
if isinstance(value, str):
49+
try:
50+
return int(value, 0) # Automatically detect radix
51+
except ValueError:
52+
try:
53+
return float(value)
54+
except ValueError:
55+
return libmissing.NA
56+
return value
4457

4558
def to_numeric(
4659
arg,
@@ -161,6 +174,7 @@ def to_numeric(
161174
2 3.0
162175
dtype: Float32
163176
"""
177+
164178
if downcast not in (None, "integer", "signed", "unsigned", "float"):
165179
raise ValueError("invalid downcasting method provided")
166180

@@ -214,15 +228,25 @@ def to_numeric(
214228
values = values.view(np.int64)
215229
else:
216230
values = ensure_object(values)
217-
coerce_numeric = errors != "raise"
218-
values, new_mask = lib.maybe_convert_numeric( # type: ignore[call-overload]
219-
values,
220-
set(),
221-
coerce_numeric=coerce_numeric,
222-
convert_to_masked_nullable=dtype_backend is not lib.no_default
223-
or isinstance(values_dtype, StringDtype)
224-
and values_dtype.na_value is libmissing.NA,
225-
)
231+
parsed_values = []
232+
new_mask = []
233+
234+
for idx, x in enumerate(values):
235+
parsed_value = parse_numeric(x)
236+
if libmissing.checknull(parsed_value):
237+
if errors == 'raise':
238+
raise ValueError(f"Unable to parse string '{x}' at position {idx}")
239+
elif errors == 'coerce':
240+
parsed_values.append(libmissing.NA)
241+
new_mask.append(True)
242+
continue
243+
else:
244+
parsed_values.append(parsed_value)
245+
new_mask.append(False)
246+
247+
values = np.array(parsed_values, dtype=object)
248+
new_mask = np.array(new_mask, dtype=bool)
249+
226250

227251
if new_mask is not None:
228252
# Remove unnecessary values, is expected later anyway and enables

0 commit comments

Comments
 (0)