Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BUG: accept strings in FloatingArray._from_sequence #45424

Merged
merged 4 commits into from
Jan 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/source/whatsnew/v1.5.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ Conversion
- Bug in constructing a :class:`Series` from a float-containing list or a floating-dtype ndarray-like (e.g. ``dask.Array``) and an integer dtype raising instead of casting like we would with an ``np.ndarray`` (:issue:`40110`)
- Bug in :meth:`Float64Index.astype` to unsigned integer dtype incorrectly casting to ``np.int64`` dtype (:issue:`45309`)
- Bug in :meth:`Series.astype` and :meth:`DataFrame.astype` from floating dtype to unsigned integer dtype failing to raise in the presence of negative values (:issue:`45151`)
- Bug in :func:`array` with ``FloatingDtype`` and values containing float-castable strings incorrectly raising (:issue:`45424`)
-

Strings
Expand Down
3 changes: 2 additions & 1 deletion pandas/core/arrays/floating.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
is_float_dtype,
is_integer_dtype,
is_object_dtype,
is_string_dtype,
)
from pandas.core.dtypes.dtypes import register_extension_dtype

Expand Down Expand Up @@ -112,7 +113,7 @@ def coerce_to_array(
return values, mask

values = np.array(values, copy=copy)
if is_object_dtype(values.dtype):
if is_object_dtype(values.dtype) or is_string_dtype(values.dtype):
inferred_type = lib.infer_dtype(values, skipna=True)
if inferred_type == "empty":
pass
Expand Down
10 changes: 10 additions & 0 deletions pandas/tests/arrays/categorical/test_astype.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,16 @@ def test_astype_str_int_categories_to_nullable_int(self):
expected = array(codes, dtype="Int64")
tm.assert_extension_array_equal(res, expected)

def test_astype_str_int_categories_to_nullable_float(self):
# GH#39616
dtype = CategoricalDtype([str(i / 2) for i in range(5)])
codes = np.random.randint(5, size=20)
arr = Categorical.from_codes(codes, dtype=dtype)

res = arr.astype("Float64")
expected = array(codes, dtype="Float64") / 2
tm.assert_extension_array_equal(res, expected)

@pytest.mark.parametrize("ordered", [True, False])
def test_astype(self, ordered):
# string
Expand Down
14 changes: 13 additions & 1 deletion pandas/tests/arrays/floating/test_construction.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,6 @@ def test_to_array_mixed_integer_float():
"values",
[
["foo", "bar"],
["1", "2"],
"foo",
1,
1.0,
Expand All @@ -132,12 +131,25 @@ def test_to_array_error(values):
"values must be a 1D list-like",
"Cannot pass scalar",
r"float\(\) argument must be a string or a (real )?number, not 'dict'",
"could not convert string to float: 'foo'",
]
)
with pytest.raises((TypeError, ValueError), match=msg):
pd.array(values, dtype="Float64")


@pytest.mark.parametrize("values", [["1", "2", None], ["1.5", "2", None]])
def test_construct_from_float_strings(values):
# see also test_to_integer_array_str
expected = pd.array([float(values[0]), 2, None], dtype="Float64")

res = pd.array(values, dtype="Float64")
tm.assert_extension_array_equal(res, expected)

res = FloatingArray._from_sequence(values)
tm.assert_extension_array_equal(res, expected)


def test_to_array_inferred_dtype():
# if values has dtype -> respect it
result = pd.array(np.array([1, 2], dtype="float32"))
Expand Down