Skip to content

Commit 28ff696

Browse files
jbrockmendelproost
authored andcommitted
DEPR: dropna multiple axes, fillna int for td64, from_codes with floats, Series.nonzero (pandas-dev#29875)
1 parent 24cc9dd commit 28ff696

File tree

8 files changed

+52
-140
lines changed

8 files changed

+52
-140
lines changed

doc/source/whatsnew/v1.0.0.rst

+4
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,10 @@ or ``matplotlib.Axes.plot``. See :ref:`plotting.formatters` for more.
459459
- In :func:`concat` the default value for ``sort`` has been changed from ``None`` to ``False`` (:issue:`20613`)
460460
- Removed previously deprecated "raise_conflict" argument from :meth:`DataFrame.update`, use "errors" instead (:issue:`23585`)
461461
- Removed previously deprecated keyword "n" from :meth:`DatetimeIndex.shift`, :meth:`TimedeltaIndex.shift`, :meth:`PeriodIndex.shift`, use "periods" instead (:issue:`22458`)
462+
- Passing an integer to :meth:`Series.fillna` or :meth:`DataFrame.fillna` with ``timedelta64[ns]`` dtype now raises ``TypeError`` (:issue:`24694`)
463+
- Passing multiple axes to :meth:`DataFrame.dropna` is no longer supported (:issue:`20995`)
464+
- Removed previously deprecated :meth:`Series.nonzero`, use `to_numpy().nonzero()` instead (:issue:`24048`)
465+
- Passing floating dtype ``codes`` to :meth:`Categorical.from_codes` is no longer supported, pass ``codes.astype(np.int64)`` instead (:issue:`21775`)
462466
- Removed the previously deprecated :meth:`Series.to_dense`, :meth:`DataFrame.to_dense` (:issue:`26684`)
463467
- Removed the previously deprecated :meth:`Index.dtype_str`, use ``str(index.dtype)`` instead (:issue:`27106`)
464468
- :meth:`Categorical.ravel` returns a :class:`Categorical` instead of a ``ndarray`` (:issue:`27199`)

pandas/core/arrays/categorical.py

+1-17
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
is_dict_like,
2828
is_dtype_equal,
2929
is_extension_array_dtype,
30-
is_float_dtype,
3130
is_integer_dtype,
3231
is_iterator,
3332
is_list_like,
@@ -646,22 +645,7 @@ def from_codes(cls, codes, categories=None, ordered=None, dtype=None):
646645

647646
codes = np.asarray(codes) # #21767
648647
if len(codes) and not is_integer_dtype(codes):
649-
msg = "codes need to be array-like integers"
650-
if is_float_dtype(codes):
651-
icodes = codes.astype("i8")
652-
if (icodes == codes).all():
653-
msg = None
654-
codes = icodes
655-
warn(
656-
(
657-
"float codes will be disallowed in the future and "
658-
"raise a ValueError"
659-
),
660-
FutureWarning,
661-
stacklevel=2,
662-
)
663-
if msg:
664-
raise ValueError(msg)
648+
raise ValueError("codes need to be array-like integers")
665649

666650
if len(codes) and (codes.max() >= len(dtype.categories) or codes.min() < -1):
667651
raise ValueError("codes need to be between -1 and len(categories)-1")

pandas/core/frame.py

+26-34
Original file line numberDiff line numberDiff line change
@@ -4475,7 +4475,7 @@ def dropna(self, axis=0, how="any", thresh=None, subset=None, inplace=False):
44754475
* 0, or 'index' : Drop rows which contain missing values.
44764476
* 1, or 'columns' : Drop columns which contain missing value.
44774477
4478-
.. deprecated:: 0.23.0
4478+
.. versionchanged:: 1.0.0
44794479
44804480
Pass tuple or list to drop on multiple axes.
44814481
Only a single axis is allowed.
@@ -4565,43 +4565,35 @@ def dropna(self, axis=0, how="any", thresh=None, subset=None, inplace=False):
45654565
inplace = validate_bool_kwarg(inplace, "inplace")
45664566
if isinstance(axis, (tuple, list)):
45674567
# GH20987
4568-
msg = (
4569-
"supplying multiple axes to axis is deprecated and "
4570-
"will be removed in a future version."
4571-
)
4572-
warnings.warn(msg, FutureWarning, stacklevel=2)
4568+
raise TypeError("supplying multiple axes to axis is no longer supported.")
45734569

4574-
result = self
4575-
for ax in axis:
4576-
result = result.dropna(how=how, thresh=thresh, subset=subset, axis=ax)
4570+
axis = self._get_axis_number(axis)
4571+
agg_axis = 1 - axis
4572+
4573+
agg_obj = self
4574+
if subset is not None:
4575+
ax = self._get_axis(agg_axis)
4576+
indices = ax.get_indexer_for(subset)
4577+
check = indices == -1
4578+
if check.any():
4579+
raise KeyError(list(np.compress(check, subset)))
4580+
agg_obj = self.take(indices, axis=agg_axis)
4581+
4582+
count = agg_obj.count(axis=agg_axis)
4583+
4584+
if thresh is not None:
4585+
mask = count >= thresh
4586+
elif how == "any":
4587+
mask = count == len(agg_obj._get_axis(agg_axis))
4588+
elif how == "all":
4589+
mask = count > 0
45774590
else:
4578-
axis = self._get_axis_number(axis)
4579-
agg_axis = 1 - axis
4580-
4581-
agg_obj = self
4582-
if subset is not None:
4583-
ax = self._get_axis(agg_axis)
4584-
indices = ax.get_indexer_for(subset)
4585-
check = indices == -1
4586-
if check.any():
4587-
raise KeyError(list(np.compress(check, subset)))
4588-
agg_obj = self.take(indices, axis=agg_axis)
4589-
4590-
count = agg_obj.count(axis=agg_axis)
4591-
4592-
if thresh is not None:
4593-
mask = count >= thresh
4594-
elif how == "any":
4595-
mask = count == len(agg_obj._get_axis(agg_axis))
4596-
elif how == "all":
4597-
mask = count > 0
4591+
if how is not None:
4592+
raise ValueError("invalid how option: {h}".format(h=how))
45984593
else:
4599-
if how is not None:
4600-
raise ValueError("invalid how option: {h}".format(h=how))
4601-
else:
4602-
raise TypeError("must specify how or thresh")
4594+
raise TypeError("must specify how or thresh")
46034595

4604-
result = self.loc(axis=axis)[mask]
4596+
result = self.loc(axis=axis)[mask]
46054597

46064598
if inplace:
46074599
self._update_inplace(result)

pandas/core/internals/blocks.py

+4-8
Original file line numberDiff line numberDiff line change
@@ -2444,15 +2444,11 @@ def fillna(self, value, **kwargs):
24442444
# interpreted as nanoseconds
24452445
if is_integer(value):
24462446
# Deprecation GH#24694, GH#19233
2447-
warnings.warn(
2448-
"Passing integers to fillna is deprecated, will "
2449-
"raise a TypeError in a future version. To retain "
2450-
"the old behavior, pass pd.Timedelta(seconds=n) "
2451-
"instead.",
2452-
FutureWarning,
2453-
stacklevel=6,
2447+
raise TypeError(
2448+
"Passing integers to fillna for timedelta64[ns] dtype is no "
2449+
"longer supporetd. To obtain the old behavior, pass "
2450+
"`pd.Timedelta(seconds=n)` instead."
24542451
)
2455-
value = Timedelta(value, unit="s")
24562452
return super().fillna(value, **kwargs)
24572453

24582454
def should_store(self, value):

pandas/core/series.py

-49
Original file line numberDiff line numberDiff line change
@@ -528,55 +528,6 @@ def compress(self, condition, *args, **kwargs):
528528
nv.validate_compress(args, kwargs)
529529
return self[condition]
530530

531-
def nonzero(self):
532-
"""
533-
Return the *integer* indices of the elements that are non-zero.
534-
535-
.. deprecated:: 0.24.0
536-
Please use .to_numpy().nonzero() as a replacement.
537-
538-
This method is equivalent to calling `numpy.nonzero` on the
539-
series data. For compatibility with NumPy, the return value is
540-
the same (a tuple with an array of indices for each dimension),
541-
but it will always be a one-item tuple because series only have
542-
one dimension.
543-
544-
Returns
545-
-------
546-
numpy.ndarray
547-
Indices of elements that are non-zero.
548-
549-
See Also
550-
--------
551-
numpy.nonzero
552-
553-
Examples
554-
--------
555-
>>> s = pd.Series([0, 3, 0, 4])
556-
>>> s.nonzero()
557-
(array([1, 3]),)
558-
>>> s.iloc[s.nonzero()[0]]
559-
1 3
560-
3 4
561-
dtype: int64
562-
563-
# same return although index of s is different
564-
>>> s = pd.Series([0, 3, 0, 4], index=['a', 'b', 'c', 'd'])
565-
>>> s.nonzero()
566-
(array([1, 3]),)
567-
>>> s.iloc[s.nonzero()[0]]
568-
b 3
569-
d 4
570-
dtype: int64
571-
"""
572-
msg = (
573-
"Series.nonzero() is deprecated "
574-
"and will be removed in a future version."
575-
"Use Series.to_numpy().nonzero() instead"
576-
)
577-
warnings.warn(msg, FutureWarning, stacklevel=2)
578-
return self._values.nonzero()
579-
580531
def put(self, *args, **kwargs):
581532
"""
582533
Apply the `put` method to its `values` attribute if it has one.

pandas/tests/arrays/categorical/test_constructors.py

+4-6
Original file line numberDiff line numberDiff line change
@@ -529,13 +529,11 @@ def test_from_codes_with_float(self):
529529
# empty codes should not raise for floats
530530
Categorical.from_codes([], dtype.categories)
531531

532-
with tm.assert_produces_warning(FutureWarning):
533-
cat = Categorical.from_codes(codes, dtype.categories)
534-
tm.assert_numpy_array_equal(cat.codes, np.array([1, 2, 0], dtype="i1"))
532+
with pytest.raises(ValueError, match="codes need to be array-like integers"):
533+
Categorical.from_codes(codes, dtype.categories)
535534

536-
with tm.assert_produces_warning(FutureWarning):
537-
cat = Categorical.from_codes(codes, dtype=dtype)
538-
tm.assert_numpy_array_equal(cat.codes, np.array([1, 2, 0], dtype="i1"))
535+
with pytest.raises(ValueError, match="codes need to be array-like integers"):
536+
Categorical.from_codes(codes, dtype=dtype)
539537

540538
codes = [1.1, 2.0, 0] # non-integer
541539
with pytest.raises(ValueError, match="codes need to be array-like integers"):

pandas/tests/frame/test_missing.py

+5-12
Original file line numberDiff line numberDiff line change
@@ -165,23 +165,16 @@ def test_dropna_multiple_axes(self):
165165
[7, np.nan, 8, 9],
166166
]
167167
)
168-
cp = df.copy()
169168

170169
# GH20987
171-
with tm.assert_produces_warning(FutureWarning):
172-
result = df.dropna(how="all", axis=[0, 1])
173-
with tm.assert_produces_warning(FutureWarning):
174-
result2 = df.dropna(how="all", axis=(0, 1))
175-
expected = df.dropna(how="all").dropna(how="all", axis=1)
176-
177-
tm.assert_frame_equal(result, expected)
178-
tm.assert_frame_equal(result2, expected)
179-
tm.assert_frame_equal(df, cp)
170+
with pytest.raises(TypeError, match="supplying multiple axes"):
171+
df.dropna(how="all", axis=[0, 1])
172+
with pytest.raises(TypeError, match="supplying multiple axes"):
173+
df.dropna(how="all", axis=(0, 1))
180174

181175
inp = df.copy()
182-
with tm.assert_produces_warning(FutureWarning):
176+
with pytest.raises(TypeError, match="supplying multiple axes"):
183177
inp.dropna(how="all", axis=(0, 1), inplace=True)
184-
tm.assert_frame_equal(inp, expected)
185178

186179
def test_dropna_tz_aware_datetime(self):
187180
# GH13407

pandas/tests/series/test_missing.py

+8-14
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
MultiIndex,
1717
NaT,
1818
Series,
19+
Timedelta,
1920
Timestamp,
2021
date_range,
2122
isna,
@@ -60,8 +61,7 @@ def test_timedelta_fillna(self):
6061
td = s.diff()
6162

6263
# reg fillna
63-
with tm.assert_produces_warning(FutureWarning):
64-
result = td.fillna(0)
64+
result = td.fillna(Timedelta(seconds=0))
6565
expected = Series(
6666
[
6767
timedelta(0),
@@ -73,8 +73,10 @@ def test_timedelta_fillna(self):
7373
tm.assert_series_equal(result, expected)
7474

7575
# interpreted as seconds, deprecated
76-
with tm.assert_produces_warning(FutureWarning):
77-
result = td.fillna(1)
76+
with pytest.raises(TypeError, match="Passing integers to fillna"):
77+
td.fillna(1)
78+
79+
result = td.fillna(Timedelta(seconds=1))
7880
expected = Series(
7981
[
8082
timedelta(seconds=1),
@@ -122,16 +124,14 @@ def test_timedelta_fillna(self):
122124
# ffill
123125
td[2] = np.nan
124126
result = td.ffill()
125-
with tm.assert_produces_warning(FutureWarning):
126-
expected = td.fillna(0)
127+
expected = td.fillna(Timedelta(seconds=0))
127128
expected[0] = np.nan
128129
tm.assert_series_equal(result, expected)
129130

130131
# bfill
131132
td[2] = np.nan
132133
result = td.bfill()
133-
with tm.assert_produces_warning(FutureWarning):
134-
expected = td.fillna(0)
134+
expected = td.fillna(Timedelta(seconds=0))
135135
expected[2] = timedelta(days=1, seconds=9 * 3600 + 60 + 1)
136136
tm.assert_series_equal(result, expected)
137137

@@ -1597,12 +1597,6 @@ def test_series_interpolate_intraday(self):
15971597

15981598
tm.assert_numpy_array_equal(result.values, exp.values)
15991599

1600-
def test_nonzero_warning(self):
1601-
# GH 24048
1602-
ser = pd.Series([1, 0, 3, 4])
1603-
with tm.assert_produces_warning(FutureWarning):
1604-
ser.nonzero()
1605-
16061600
@pytest.mark.parametrize(
16071601
"ind",
16081602
[

0 commit comments

Comments
 (0)