Skip to content

Commit

Permalink
BUG (string dtype): let fillna with invalid value upcast to object dt…
Browse files Browse the repository at this point in the history
…ype (pandas-dev#60296)

* BUG (string dtype): let fillna with invalid value upcast to object dtype

* fix fillna limit case + update tests for no longer raising
  • Loading branch information
jorisvandenbossche authored Nov 14, 2024
1 parent 9bee2f0 commit 34c39e9
Show file tree
Hide file tree
Showing 3 changed files with 6 additions and 16 deletions.
9 changes: 5 additions & 4 deletions pandas/core/internals/blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@
PeriodArray,
TimedeltaArray,
)
from pandas.core.arrays.string_ import StringDtype
from pandas.core.base import PandasObject
import pandas.core.common as com
from pandas.core.computation import expressions
Expand Down Expand Up @@ -1336,7 +1337,7 @@ def fillna(
return [self.copy(deep=False)]

if limit is not None:
mask[mask.cumsum(self.ndim - 1) > limit] = False
mask[mask.cumsum(self.values.ndim - 1) > limit] = False

if inplace:
nbs = self.putmask(mask.T, value)
Expand Down Expand Up @@ -1684,7 +1685,7 @@ def where(self, other, cond) -> list[Block]:
res_values = arr._where(cond, other).T
except (ValueError, TypeError):
if self.ndim == 1 or self.shape[0] == 1:
if isinstance(self.dtype, IntervalDtype):
if isinstance(self.dtype, (IntervalDtype, StringDtype)):
# TestSetitemFloatIntervalWithIntIntervalValues
blk = self.coerce_to_target_dtype(orig_other, raise_on_upcast=False)
return blk.where(orig_other, orig_cond)
Expand Down Expand Up @@ -1854,9 +1855,9 @@ def fillna(
limit: int | None = None,
inplace: bool = False,
) -> list[Block]:
if isinstance(self.dtype, IntervalDtype):
if isinstance(self.dtype, (IntervalDtype, StringDtype)):
# Block.fillna handles coercion (test_fillna_interval)
if limit is not None:
if isinstance(self.dtype, IntervalDtype) and limit is not None:
raise ValueError("limit must be None")
return super().fillna(
value=value,
Expand Down
8 changes: 1 addition & 7 deletions pandas/tests/frame/indexing/test_where.py
Original file line number Diff line number Diff line change
Expand Up @@ -1025,15 +1025,9 @@ def test_where_producing_ea_cond_for_np_dtype():
@pytest.mark.parametrize(
"replacement", [0.001, True, "snake", None, datetime(2022, 5, 4)]
)
def test_where_int_overflow(replacement, using_infer_string):
def test_where_int_overflow(replacement):
# GH 31687
df = DataFrame([[1.0, 2e25, "nine"], [np.nan, 0.1, None]])
if using_infer_string and replacement not in (None, "snake"):
with pytest.raises(
TypeError, match=f"Invalid value '{replacement}' for dtype 'str'"
):
df.where(pd.notnull(df), replacement)
return
result = df.where(pd.notnull(df), replacement)
expected = DataFrame([[1.0, 2e25, "nine"], [replacement, 0.1, replacement]])

Expand Down
5 changes: 0 additions & 5 deletions pandas/tests/series/indexing/test_setitem.py
Original file line number Diff line number Diff line change
Expand Up @@ -839,11 +839,6 @@ def test_series_where(self, obj, key, expected, raises, val, is_inplace):
obj = obj.copy()
arr = obj._values

if raises and obj.dtype == "string":
with pytest.raises(TypeError, match="Invalid value"):
obj.where(~mask, val)
return

res = obj.where(~mask, val)

if val is NA and res.dtype == object:
Expand Down

0 comments on commit 34c39e9

Please sign in to comment.