diff --git a/doc/source/whatsnew/v1.0.0.rst b/doc/source/whatsnew/v1.0.0.rst index 7d3f61ccf4e9f..42e28e0556d18 100644 --- a/doc/source/whatsnew/v1.0.0.rst +++ b/doc/source/whatsnew/v1.0.0.rst @@ -459,6 +459,10 @@ or ``matplotlib.Axes.plot``. See :ref:`plotting.formatters` for more. - In :func:`concat` the default value for ``sort`` has been changed from ``None`` to ``False`` (:issue:`20613`) - Removed previously deprecated "raise_conflict" argument from :meth:`DataFrame.update`, use "errors" instead (:issue:`23585`) - Removed previously deprecated keyword "n" from :meth:`DatetimeIndex.shift`, :meth:`TimedeltaIndex.shift`, :meth:`PeriodIndex.shift`, use "periods" instead (:issue:`22458`) +- Passing an integer to :meth:`Series.fillna` or :meth:`DataFrame.fillna` with ``timedelta64[ns]`` dtype now raises ``TypeError`` (:issue:`24694`) +- Passing multiple axes to :meth:`DataFrame.dropna` is no longer supported (:issue:`20995`) +- Removed previously deprecated :meth:`Series.nonzero`, use `to_numpy().nonzero()` instead (:issue:`24048`) +- Passing floating dtype ``codes`` to :meth:`Categorical.from_codes` is no longer supported, pass ``codes.astype(np.int64)`` instead (:issue:`21775`) - Removed the previously deprecated :meth:`Series.to_dense`, :meth:`DataFrame.to_dense` (:issue:`26684`) - Removed the previously deprecated :meth:`Index.dtype_str`, use ``str(index.dtype)`` instead (:issue:`27106`) - :meth:`Categorical.ravel` returns a :class:`Categorical` instead of a ``ndarray`` (:issue:`27199`) diff --git a/pandas/core/arrays/categorical.py b/pandas/core/arrays/categorical.py index 0dc972011833a..46aab31770fde 100644 --- a/pandas/core/arrays/categorical.py +++ b/pandas/core/arrays/categorical.py @@ -27,7 +27,6 @@ is_dict_like, is_dtype_equal, is_extension_array_dtype, - is_float_dtype, is_integer_dtype, is_iterator, is_list_like, @@ -646,22 +645,7 @@ def from_codes(cls, codes, categories=None, ordered=None, dtype=None): codes = np.asarray(codes) # #21767 if len(codes) and not is_integer_dtype(codes): - msg = "codes need to be array-like integers" - if is_float_dtype(codes): - icodes = codes.astype("i8") - if (icodes == codes).all(): - msg = None - codes = icodes - warn( - ( - "float codes will be disallowed in the future and " - "raise a ValueError" - ), - FutureWarning, - stacklevel=2, - ) - if msg: - raise ValueError(msg) + raise ValueError("codes need to be array-like integers") if len(codes) and (codes.max() >= len(dtype.categories) or codes.min() < -1): raise ValueError("codes need to be between -1 and len(categories)-1") diff --git a/pandas/core/frame.py b/pandas/core/frame.py index ca943111b7e9f..0b690363a2178 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -4475,7 +4475,7 @@ def dropna(self, axis=0, how="any", thresh=None, subset=None, inplace=False): * 0, or 'index' : Drop rows which contain missing values. * 1, or 'columns' : Drop columns which contain missing value. - .. deprecated:: 0.23.0 + .. versionchanged:: 1.0.0 Pass tuple or list to drop on multiple axes. Only a single axis is allowed. @@ -4565,43 +4565,35 @@ def dropna(self, axis=0, how="any", thresh=None, subset=None, inplace=False): inplace = validate_bool_kwarg(inplace, "inplace") if isinstance(axis, (tuple, list)): # GH20987 - msg = ( - "supplying multiple axes to axis is deprecated and " - "will be removed in a future version." - ) - warnings.warn(msg, FutureWarning, stacklevel=2) + raise TypeError("supplying multiple axes to axis is no longer supported.") - result = self - for ax in axis: - result = result.dropna(how=how, thresh=thresh, subset=subset, axis=ax) + axis = self._get_axis_number(axis) + agg_axis = 1 - axis + + agg_obj = self + if subset is not None: + ax = self._get_axis(agg_axis) + indices = ax.get_indexer_for(subset) + check = indices == -1 + if check.any(): + raise KeyError(list(np.compress(check, subset))) + agg_obj = self.take(indices, axis=agg_axis) + + count = agg_obj.count(axis=agg_axis) + + if thresh is not None: + mask = count >= thresh + elif how == "any": + mask = count == len(agg_obj._get_axis(agg_axis)) + elif how == "all": + mask = count > 0 else: - axis = self._get_axis_number(axis) - agg_axis = 1 - axis - - agg_obj = self - if subset is not None: - ax = self._get_axis(agg_axis) - indices = ax.get_indexer_for(subset) - check = indices == -1 - if check.any(): - raise KeyError(list(np.compress(check, subset))) - agg_obj = self.take(indices, axis=agg_axis) - - count = agg_obj.count(axis=agg_axis) - - if thresh is not None: - mask = count >= thresh - elif how == "any": - mask = count == len(agg_obj._get_axis(agg_axis)) - elif how == "all": - mask = count > 0 + if how is not None: + raise ValueError("invalid how option: {h}".format(h=how)) else: - if how is not None: - raise ValueError("invalid how option: {h}".format(h=how)) - else: - raise TypeError("must specify how or thresh") + raise TypeError("must specify how or thresh") - result = self.loc(axis=axis)[mask] + result = self.loc(axis=axis)[mask] if inplace: self._update_inplace(result) diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index b0382755f2edb..8dd39473ee1f4 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -2444,15 +2444,11 @@ def fillna(self, value, **kwargs): # interpreted as nanoseconds if is_integer(value): # Deprecation GH#24694, GH#19233 - warnings.warn( - "Passing integers to fillna is deprecated, will " - "raise a TypeError in a future version. To retain " - "the old behavior, pass pd.Timedelta(seconds=n) " - "instead.", - FutureWarning, - stacklevel=6, + raise TypeError( + "Passing integers to fillna for timedelta64[ns] dtype is no " + "longer supporetd. To obtain the old behavior, pass " + "`pd.Timedelta(seconds=n)` instead." ) - value = Timedelta(value, unit="s") return super().fillna(value, **kwargs) def should_store(self, value): diff --git a/pandas/core/series.py b/pandas/core/series.py index 56039605651ac..a8232f137f3ef 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -528,55 +528,6 @@ def compress(self, condition, *args, **kwargs): nv.validate_compress(args, kwargs) return self[condition] - def nonzero(self): - """ - Return the *integer* indices of the elements that are non-zero. - - .. deprecated:: 0.24.0 - Please use .to_numpy().nonzero() as a replacement. - - This method is equivalent to calling `numpy.nonzero` on the - series data. For compatibility with NumPy, the return value is - the same (a tuple with an array of indices for each dimension), - but it will always be a one-item tuple because series only have - one dimension. - - Returns - ------- - numpy.ndarray - Indices of elements that are non-zero. - - See Also - -------- - numpy.nonzero - - Examples - -------- - >>> s = pd.Series([0, 3, 0, 4]) - >>> s.nonzero() - (array([1, 3]),) - >>> s.iloc[s.nonzero()[0]] - 1 3 - 3 4 - dtype: int64 - - # same return although index of s is different - >>> s = pd.Series([0, 3, 0, 4], index=['a', 'b', 'c', 'd']) - >>> s.nonzero() - (array([1, 3]),) - >>> s.iloc[s.nonzero()[0]] - b 3 - d 4 - dtype: int64 - """ - msg = ( - "Series.nonzero() is deprecated " - "and will be removed in a future version." - "Use Series.to_numpy().nonzero() instead" - ) - warnings.warn(msg, FutureWarning, stacklevel=2) - return self._values.nonzero() - def put(self, *args, **kwargs): """ Apply the `put` method to its `values` attribute if it has one. diff --git a/pandas/tests/arrays/categorical/test_constructors.py b/pandas/tests/arrays/categorical/test_constructors.py index 59017a1442cb4..14bb9b88eee88 100644 --- a/pandas/tests/arrays/categorical/test_constructors.py +++ b/pandas/tests/arrays/categorical/test_constructors.py @@ -529,13 +529,11 @@ def test_from_codes_with_float(self): # empty codes should not raise for floats Categorical.from_codes([], dtype.categories) - with tm.assert_produces_warning(FutureWarning): - cat = Categorical.from_codes(codes, dtype.categories) - tm.assert_numpy_array_equal(cat.codes, np.array([1, 2, 0], dtype="i1")) + with pytest.raises(ValueError, match="codes need to be array-like integers"): + Categorical.from_codes(codes, dtype.categories) - with tm.assert_produces_warning(FutureWarning): - cat = Categorical.from_codes(codes, dtype=dtype) - tm.assert_numpy_array_equal(cat.codes, np.array([1, 2, 0], dtype="i1")) + with pytest.raises(ValueError, match="codes need to be array-like integers"): + Categorical.from_codes(codes, dtype=dtype) codes = [1.1, 2.0, 0] # non-integer with pytest.raises(ValueError, match="codes need to be array-like integers"): diff --git a/pandas/tests/frame/test_missing.py b/pandas/tests/frame/test_missing.py index 24510ff9338ca..0b77c0067e5f2 100644 --- a/pandas/tests/frame/test_missing.py +++ b/pandas/tests/frame/test_missing.py @@ -165,23 +165,16 @@ def test_dropna_multiple_axes(self): [7, np.nan, 8, 9], ] ) - cp = df.copy() # GH20987 - with tm.assert_produces_warning(FutureWarning): - result = df.dropna(how="all", axis=[0, 1]) - with tm.assert_produces_warning(FutureWarning): - result2 = df.dropna(how="all", axis=(0, 1)) - expected = df.dropna(how="all").dropna(how="all", axis=1) - - tm.assert_frame_equal(result, expected) - tm.assert_frame_equal(result2, expected) - tm.assert_frame_equal(df, cp) + with pytest.raises(TypeError, match="supplying multiple axes"): + df.dropna(how="all", axis=[0, 1]) + with pytest.raises(TypeError, match="supplying multiple axes"): + df.dropna(how="all", axis=(0, 1)) inp = df.copy() - with tm.assert_produces_warning(FutureWarning): + with pytest.raises(TypeError, match="supplying multiple axes"): inp.dropna(how="all", axis=(0, 1), inplace=True) - tm.assert_frame_equal(inp, expected) def test_dropna_tz_aware_datetime(self): # GH13407 diff --git a/pandas/tests/series/test_missing.py b/pandas/tests/series/test_missing.py index 81bf1edbe86df..09f1db25a3e31 100644 --- a/pandas/tests/series/test_missing.py +++ b/pandas/tests/series/test_missing.py @@ -16,6 +16,7 @@ MultiIndex, NaT, Series, + Timedelta, Timestamp, date_range, isna, @@ -60,8 +61,7 @@ def test_timedelta_fillna(self): td = s.diff() # reg fillna - with tm.assert_produces_warning(FutureWarning): - result = td.fillna(0) + result = td.fillna(Timedelta(seconds=0)) expected = Series( [ timedelta(0), @@ -73,8 +73,10 @@ def test_timedelta_fillna(self): tm.assert_series_equal(result, expected) # interpreted as seconds, deprecated - with tm.assert_produces_warning(FutureWarning): - result = td.fillna(1) + with pytest.raises(TypeError, match="Passing integers to fillna"): + td.fillna(1) + + result = td.fillna(Timedelta(seconds=1)) expected = Series( [ timedelta(seconds=1), @@ -122,16 +124,14 @@ def test_timedelta_fillna(self): # ffill td[2] = np.nan result = td.ffill() - with tm.assert_produces_warning(FutureWarning): - expected = td.fillna(0) + expected = td.fillna(Timedelta(seconds=0)) expected[0] = np.nan tm.assert_series_equal(result, expected) # bfill td[2] = np.nan result = td.bfill() - with tm.assert_produces_warning(FutureWarning): - expected = td.fillna(0) + expected = td.fillna(Timedelta(seconds=0)) expected[2] = timedelta(days=1, seconds=9 * 3600 + 60 + 1) tm.assert_series_equal(result, expected) @@ -1597,12 +1597,6 @@ def test_series_interpolate_intraday(self): tm.assert_numpy_array_equal(result.values, exp.values) - def test_nonzero_warning(self): - # GH 24048 - ser = pd.Series([1, 0, 3, 4]) - with tm.assert_produces_warning(FutureWarning): - ser.nonzero() - @pytest.mark.parametrize( "ind", [