Skip to content

Commit

Permalink
correct def fillna, fix tests
Browse files Browse the repository at this point in the history
  • Loading branch information
natmokval committed Mar 7, 2024
1 parent ddbe93b commit 9412e7f
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 97 deletions.
16 changes: 6 additions & 10 deletions pandas/core/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -6919,7 +6919,11 @@ def fillna(
stacklevel=2,
)

value, _ = validate_fillna_kwargs(value, None)
if isinstance(value, (list, tuple)):
raise TypeError(
'"value" parameter must be a scalar or dict, but '
f'you passed a "{type(value).__name__}"'
)

# set the default here, so functions examining the signaure
# can detect if something was set (e.g. in groupby) (GH9221)
Expand All @@ -6928,15 +6932,7 @@ def fillna(
axis = self._get_axis_number(axis)

if value is None:
return self._pad_or_backfill(
# error: Argument 1 to "_pad_or_backfill" of "NDFrame" has
# incompatible type "Optional[Literal['backfill', 'bfill', 'ffill',
# 'pad']]"; expected "Literal['ffill', 'bfill', 'pad', 'backfill']"
method=None, # type: ignore[arg-type]
axis=axis,
limit=limit,
inplace=inplace,
)
raise ValueError("Must specify a fill 'value'.")
else:
if self.ndim == 1:
if isinstance(value, (dict, ABCSeries)):
Expand Down
8 changes: 1 addition & 7 deletions pandas/tests/extension/base/missing.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,6 @@ def test_fillna_scalar(self, data_missing):
expected = data_missing.fillna(valid)
tm.assert_extension_array_equal(result, expected)

@pytest.mark.filterwarnings(
"ignore:Series.fillna with 'method' is deprecated:FutureWarning"
)
def test_fillna_limit_pad(self, data_missing):
arr = data_missing.take([1, 0, 0, 0, 1])
result = pd.Series(arr).ffill(limit=2)
Expand Down Expand Up @@ -99,12 +96,9 @@ def test_ffill_limit_area(
expected = pd.Series(data_missing.take(expected_ilocs))
tm.assert_series_equal(result, expected)

@pytest.mark.filterwarnings(
"ignore:Series.fillna with 'method' is deprecated:FutureWarning"
)
def test_fillna_limit_backfill(self, data_missing):
arr = data_missing.take([1, 0, 0, 0, 1])
result = pd.Series(arr).fillna(method="backfill", limit=2)
result = pd.Series(arr).bfill(limit=2)
expected = pd.Series(data_missing.take([1, 0, 1, 1, 1]))
tm.assert_series_equal(result, expected)

Expand Down
9 changes: 0 additions & 9 deletions pandas/tests/extension/decimal/test_decimal.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,15 +187,6 @@ def test_ffill_limit_area(
)

def test_fillna_limit_backfill(self, data_missing):
msg = "Series.fillna with 'method' is deprecated"
with tm.assert_produces_warning(
FutureWarning,
match=msg,
check_stacklevel=False,
raise_on_extra_warnings=False,
):
super().test_fillna_limit_backfill(data_missing)

msg = "ExtensionArray.fillna 'method' keyword is deprecated"
with tm.assert_produces_warning(
DeprecationWarning,
Expand Down
4 changes: 1 addition & 3 deletions pandas/tests/extension/test_sparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,9 +235,7 @@ def test_isna(self, data_missing):
tm.assert_equal(sarr.isna(), expected)

def test_fillna_limit_backfill(self, data_missing):
warns = FutureWarning
with tm.assert_produces_warning(warns, check_stacklevel=False):
super().test_fillna_limit_backfill(data_missing)
super().test_fillna_limit_backfill(data_missing)

def test_fillna_no_op_returns_copy(self, data, request):
if np.isnan(data.fill_value):
Expand Down
91 changes: 23 additions & 68 deletions pandas/tests/frame/methods/test_fillna.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,20 +58,15 @@ def test_fillna_datetime(self, datetime_frame):
zero_filled = datetime_frame.fillna(0)
assert (zero_filled.loc[zero_filled.index[:5], "A"] == 0).all()

msg = "DataFrame.fillna with 'method' is deprecated"
with tm.assert_produces_warning(FutureWarning, match=msg):
padded = datetime_frame.fillna(method="pad")
padded = datetime_frame.ffill()
assert np.isnan(padded.loc[padded.index[:5], "A"]).all()
assert (
padded.loc[padded.index[-5:], "A"] == padded.loc[padded.index[-5], "A"]
).all()

msg = "Must specify a fill 'value' or 'method'"
msg = "Must specify a fill 'value'"
with pytest.raises(ValueError, match=msg):
datetime_frame.fillna()
msg = "Cannot specify both 'value' and 'method'"
with pytest.raises(ValueError, match=msg):
datetime_frame.fillna(5, method="ffill")

@pytest.mark.xfail(using_pyarrow_string_dtype(), reason="can't fill 0 in string")
def test_fillna_mixed_type(self, float_string_frame):
Expand All @@ -80,20 +75,15 @@ def test_fillna_mixed_type(self, float_string_frame):
mf.loc[mf.index[-10:], "A"] = np.nan
# TODO: make stronger assertion here, GH 25640
mf.fillna(value=0)
msg = "DataFrame.fillna with 'method' is deprecated"
with tm.assert_produces_warning(FutureWarning, match=msg):
mf.fillna(method="pad")
mf.ffill()

def test_fillna_mixed_float(self, mixed_float_frame):
# mixed numeric (but no float16)
mf = mixed_float_frame.reindex(columns=["A", "B", "D"])
mf.loc[mf.index[-10:], "A"] = np.nan
result = mf.fillna(value=0)
_check_mixed_float(result, dtype={"C": None})

msg = "DataFrame.fillna with 'method' is deprecated"
with tm.assert_produces_warning(FutureWarning, match=msg):
result = mf.fillna(method="pad")
result = mf.ffill()
_check_mixed_float(result, dtype={"C": None})

def test_fillna_different_dtype(self, using_infer_string):
Expand Down Expand Up @@ -159,9 +149,7 @@ def test_fillna_tzaware(self):
]
}
)
msg = "DataFrame.fillna with 'method' is deprecated"
with tm.assert_produces_warning(FutureWarning, match=msg):
res = df.fillna(method="pad")
res = df.ffill()
tm.assert_frame_equal(res, exp)

df = DataFrame({"A": [NaT, Timestamp("2012-11-11 00:00:00+01:00")]})
Expand All @@ -173,9 +161,7 @@ def test_fillna_tzaware(self):
]
}
)
msg = "DataFrame.fillna with 'method' is deprecated"
with tm.assert_produces_warning(FutureWarning, match=msg):
res = df.fillna(method="bfill")
res = df.bfill()
tm.assert_frame_equal(res, exp)

def test_fillna_tzaware_different_column(self):
Expand All @@ -187,9 +173,7 @@ def test_fillna_tzaware_different_column(self):
"B": [1, 2, np.nan, np.nan],
}
)
msg = "DataFrame.fillna with 'method' is deprecated"
with tm.assert_produces_warning(FutureWarning, match=msg):
result = df.fillna(method="pad")
result = df.ffill()
expected = DataFrame(
{
"A": date_range("20130101", periods=4, tz="US/Eastern"),
Expand Down Expand Up @@ -220,9 +204,7 @@ def test_na_actions_categorical(self):
with pytest.raises(TypeError, match=msg):
df.fillna(value={"cats": 4, "vals": "c"})

msg = "DataFrame.fillna with 'method' is deprecated"
with tm.assert_produces_warning(FutureWarning, match=msg):
res = df.fillna(method="pad")
res = df.ffill()
tm.assert_frame_equal(res, df_exp_fill)

# dropna
Expand Down Expand Up @@ -368,19 +350,14 @@ def test_ffill(self, datetime_frame):
datetime_frame.loc[datetime_frame.index[:5], "A"] = np.nan
datetime_frame.loc[datetime_frame.index[-5:], "A"] = np.nan

msg = "DataFrame.fillna with 'method' is deprecated"
with tm.assert_produces_warning(FutureWarning, match=msg):
alt = datetime_frame.fillna(method="ffill")
alt = datetime_frame.ffill()
tm.assert_frame_equal(datetime_frame.ffill(), alt)

def test_bfill(self, datetime_frame):
datetime_frame.loc[datetime_frame.index[:5], "A"] = np.nan
datetime_frame.loc[datetime_frame.index[-5:], "A"] = np.nan

msg = "DataFrame.fillna with 'method' is deprecated"
with tm.assert_produces_warning(FutureWarning, match=msg):
alt = datetime_frame.fillna(method="bfill")

alt = datetime_frame.bfill()
tm.assert_frame_equal(datetime_frame.bfill(), alt)

def test_frame_pad_backfill_limit(self):
Expand All @@ -389,16 +366,13 @@ def test_frame_pad_backfill_limit(self):

result = df[:2].reindex(index, method="pad", limit=5)

msg = "DataFrame.fillna with 'method' is deprecated"
with tm.assert_produces_warning(FutureWarning, match=msg):
expected = df[:2].reindex(index).fillna(method="pad")
expected = df[:2].reindex(index).ffill()
expected.iloc[-3:] = np.nan
tm.assert_frame_equal(result, expected)

result = df[-2:].reindex(index, method="backfill", limit=5)

with tm.assert_produces_warning(FutureWarning, match=msg):
expected = df[-2:].reindex(index).fillna(method="backfill")
expected = df[-2:].reindex(index).bfill()
expected.iloc[:3] = np.nan
tm.assert_frame_equal(result, expected)

Expand All @@ -407,21 +381,16 @@ def test_frame_fillna_limit(self):
df = DataFrame(np.random.default_rng(2).standard_normal((10, 4)), index=index)

result = df[:2].reindex(index)
msg = "DataFrame.fillna with 'method' is deprecated"
with tm.assert_produces_warning(FutureWarning, match=msg):
result = result.fillna(method="pad", limit=5)
result = result.ffill(limit=5)

with tm.assert_produces_warning(FutureWarning, match=msg):
expected = df[:2].reindex(index).fillna(method="pad")
expected = df[:2].reindex(index).ffill()
expected.iloc[-3:] = np.nan
tm.assert_frame_equal(result, expected)

result = df[-2:].reindex(index)
with tm.assert_produces_warning(FutureWarning, match=msg):
result = result.fillna(method="backfill", limit=5)
result = result.bfill(limit=5)

with tm.assert_produces_warning(FutureWarning, match=msg):
expected = df[-2:].reindex(index).fillna(method="backfill")
expected = df[-2:].reindex(index).bfill()
expected.iloc[:3] = np.nan
tm.assert_frame_equal(result, expected)

Expand Down Expand Up @@ -465,13 +434,10 @@ def test_fillna_inplace(self):

df.loc[:4, 1] = np.nan
df.loc[-4:, 3] = np.nan
msg = "DataFrame.fillna with 'method' is deprecated"
with tm.assert_produces_warning(FutureWarning, match=msg):
expected = df.fillna(method="ffill")
expected = df.ffill()
assert expected is not df

with tm.assert_produces_warning(FutureWarning, match=msg):
df.fillna(method="ffill", inplace=True)
df.ffill(inplace=True)
tm.assert_frame_equal(df, expected)

def test_fillna_dict_series(self):
Expand Down Expand Up @@ -542,24 +508,15 @@ def test_fillna_columns(self):
arr[:, ::2] = np.nan
df = DataFrame(arr)

msg = "DataFrame.fillna with 'method' is deprecated"
with tm.assert_produces_warning(FutureWarning, match=msg):
result = df.fillna(method="ffill", axis=1)
with tm.assert_produces_warning(FutureWarning, match=msg):
expected = df.T.fillna(method="pad").T
result = df.ffill(axis=1)
expected = df.T.ffill().T
tm.assert_frame_equal(result, expected)

df.insert(6, "foo", 5)
with tm.assert_produces_warning(FutureWarning, match=msg):
result = df.fillna(method="ffill", axis=1)
with tm.assert_produces_warning(FutureWarning, match=msg):
expected = df.astype(float).fillna(method="ffill", axis=1)
result = df.ffill(axis=1)
expected = df.astype(float).ffill(axis=1)
tm.assert_frame_equal(result, expected)

def test_fillna_invalid_method(self, float_frame):
with pytest.raises(ValueError, match="ffil"):
float_frame.fillna(method="ffil")

def test_fillna_invalid_value(self, float_frame):
# list
msg = '"value" parameter must be a scalar or dict, but you passed a "{}"'
Expand All @@ -580,9 +537,7 @@ def test_fillna_col_reordering(self):
cols = ["COL." + str(i) for i in range(5, 0, -1)]
data = np.random.default_rng(2).random((20, 5))
df = DataFrame(index=range(20), columns=cols, data=data)
msg = "DataFrame.fillna with 'method' is deprecated"
with tm.assert_produces_warning(FutureWarning, match=msg):
filled = df.fillna(method="ffill")
filled = df.ffill()
assert df.columns.tolist() == filled.columns.tolist()

@pytest.mark.xfail(using_pyarrow_string_dtype(), reason="can't fill 0 in string")
Expand Down

0 comments on commit 9412e7f

Please sign in to comment.