Skip to content

Commit 8eca4b7

Browse files
authored
BUG: fix astype conversion string -> float (#37974)
1 parent 22007d3 commit 8eca4b7

File tree

4 files changed

+39
-2
lines changed

4 files changed

+39
-2
lines changed

doc/source/whatsnew/v1.2.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,7 @@ Conversion
589589
^^^^^^^^^^
590590

591591
- Bug in :meth:`DataFrame.to_dict` with ``orient='records'`` now returns python native datetime objects for datetimelike columns (:issue:`21256`)
592+
- Bug in :meth:`Series.astype` conversion from ``string`` to ``float`` raised in presence of ``pd.NA`` values (:issue:`37626`)
592593
-
593594

594595
Strings

pandas/conftest.py

+14-1
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,6 @@ def unique_nulls_fixture(request):
288288
# Generate cartesian product of unique_nulls_fixture:
289289
unique_nulls_fixture2 = unique_nulls_fixture
290290

291-
292291
# ----------------------------------------------------------------
293292
# Classes
294293
# ----------------------------------------------------------------
@@ -1091,6 +1090,20 @@ def float_ea_dtype(request):
10911090
return request.param
10921091

10931092

1093+
@pytest.fixture(params=tm.FLOAT_DTYPES + tm.FLOAT_EA_DTYPES)
1094+
def any_float_allowed_nullable_dtype(request):
1095+
"""
1096+
Parameterized fixture for float dtypes.
1097+
1098+
* float
1099+
* 'float32'
1100+
* 'float64'
1101+
* 'Float32'
1102+
* 'Float64'
1103+
"""
1104+
return request.param
1105+
1106+
10941107
@pytest.fixture(params=tm.COMPLEX_DTYPES)
10951108
def complex_dtype(request):
10961109
"""

pandas/core/arrays/string_.py

+15-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818

1919
from pandas.core import ops
2020
from pandas.core.array_algos import masked_reductions
21-
from pandas.core.arrays import IntegerArray, PandasArray
21+
from pandas.core.arrays import FloatingArray, IntegerArray, PandasArray
22+
from pandas.core.arrays.floating import FloatingDtype
2223
from pandas.core.arrays.integer import _IntegerDtype
2324
from pandas.core.construction import extract_array
2425
from pandas.core.indexers import check_array_indexer
@@ -294,6 +295,19 @@ def astype(self, dtype, copy=True):
294295
arr[mask] = 0
295296
values = arr.astype(dtype.numpy_dtype)
296297
return IntegerArray(values, mask, copy=False)
298+
elif isinstance(dtype, FloatingDtype):
299+
arr = self.copy()
300+
mask = self.isna()
301+
arr[mask] = "0"
302+
values = arr.astype(dtype.numpy_dtype)
303+
return FloatingArray(values, mask, copy=False)
304+
elif np.issubdtype(dtype, np.floating):
305+
arr = self._ndarray.copy()
306+
mask = self.isna()
307+
arr[mask] = 0
308+
values = arr.astype(dtype)
309+
values[mask] = np.nan
310+
return values
297311

298312
return super().astype(dtype, copy)
299313

pandas/tests/arrays/string_/test_string.py

+9
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,15 @@ def test_astype_int(dtype, request):
366366
tm.assert_extension_array_equal(result, expected)
367367

368368

369+
def test_astype_float(any_float_allowed_nullable_dtype):
370+
# Don't compare arrays (37974)
371+
ser = pd.Series(["1.1", pd.NA, "3.3"], dtype="string")
372+
373+
result = ser.astype(any_float_allowed_nullable_dtype)
374+
expected = pd.Series([1.1, np.nan, 3.3], dtype=any_float_allowed_nullable_dtype)
375+
tm.assert_series_equal(result, expected)
376+
377+
369378
@pytest.mark.parametrize("skipna", [True, False])
370379
@pytest.mark.xfail(reason="Not implemented StringArray.sum")
371380
def test_reduce(skipna, dtype):

0 commit comments

Comments
 (0)