diff --git a/doc/source/whatsnew/v2.2.0.rst b/doc/source/whatsnew/v2.2.0.rst index b30a11dca7c57..65271886c5769 100644 --- a/doc/source/whatsnew/v2.2.0.rst +++ b/doc/source/whatsnew/v2.2.0.rst @@ -362,6 +362,7 @@ Other Deprecations - Deprecated :func:`read_gbq` and :meth:`DataFrame.to_gbq`. Use ``pandas_gbq.read_gbq`` and ``pandas_gbq.to_gbq`` instead https://pandas-gbq.readthedocs.io/en/latest/api.html (:issue:`55525`) - Deprecated :meth:`.DataFrameGroupBy.fillna` and :meth:`.SeriesGroupBy.fillna`; use :meth:`.DataFrameGroupBy.ffill`, :meth:`.DataFrameGroupBy.bfill` for forward and backward filling or :meth:`.DataFrame.fillna` to fill with a single value (or the Series equivalents) (:issue:`55718`) - Deprecated :meth:`Index.format`, use ``index.astype(str)`` or ``index.map(formatter)`` instead (:issue:`55413`) +- Deprecated :meth:`Series.ravel`, the underlying array is already 1D, so ravel is not necessary (:issue:`52511`) - Deprecated :meth:`Series.view`, use ``astype`` instead to change the dtype (:issue:`20251`) - Deprecated ``core.internals`` members ``Block``, ``ExtensionBlock``, and ``DatetimeTZBlock``, use public APIs instead (:issue:`55139`) - Deprecated ``year``, ``month``, ``quarter``, ``day``, ``hour``, ``minute``, and ``second`` keywords in the :class:`PeriodIndex` constructor, use :meth:`PeriodIndex.from_fields` instead (:issue:`55960`) diff --git a/pandas/_testing/asserters.py b/pandas/_testing/asserters.py index 0d8fb7bfce33a..55cf734c32eae 100644 --- a/pandas/_testing/asserters.py +++ b/pandas/_testing/asserters.py @@ -426,6 +426,8 @@ def assert_is_valid_plot_return_object(objs) -> None: from matplotlib.axes import Axes if isinstance(objs, (Series, np.ndarray)): + if isinstance(objs, Series): + objs = objs._values for el in objs.ravel(): msg = ( "one of 'objs' is not a matplotlib Axes instance, " diff --git a/pandas/core/dtypes/cast.py b/pandas/core/dtypes/cast.py index 792fa4fdc24a5..320f028f4484c 100644 --- a/pandas/core/dtypes/cast.py +++ b/pandas/core/dtypes/cast.py @@ -261,6 +261,8 @@ def maybe_downcast_to_dtype(result: ArrayLike, dtype: str | np.dtype) -> ArrayLi try to cast to the specified dtype (e.g. convert back to bool/int or could be an astype of float64->float32 """ + if isinstance(result, ABCSeries): + result = result._values do_round = False if isinstance(dtype, str): diff --git a/pandas/core/reshape/pivot.py b/pandas/core/reshape/pivot.py index c39fbfe6b6d33..eba4f72b5eb8f 100644 --- a/pandas/core/reshape/pivot.py +++ b/pandas/core/reshape/pivot.py @@ -309,6 +309,7 @@ def _add_margins( row_names = result.index.names # check the result column and leave floats + for dtype in set(result.dtypes): if isinstance(dtype, ExtensionDtype): # Can hold NA already diff --git a/pandas/core/series.py b/pandas/core/series.py index 6b06786549ade..758476f5e5fea 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -847,6 +847,11 @@ def ravel(self, order: str = "C") -> ArrayLike: """ Return the flattened underlying data as an ndarray or ExtensionArray. + .. deprecated:: 2.2.0 + Series.ravel is deprecated. The underlying array is already 1D, so + ravel is not necessary. Use :meth:`to_numpy` for conversion to a numpy + array instead. + Returns ------- numpy.ndarray or ExtensionArray @@ -859,9 +864,16 @@ def ravel(self, order: str = "C") -> ArrayLike: Examples -------- >>> s = pd.Series([1, 2, 3]) - >>> s.ravel() + >>> s.ravel() # doctest: +SKIP array([1, 2, 3]) """ + warnings.warn( + "Series.ravel is deprecated. The underlying array is already 1D, so " + "ravel is not necessary. Use `to_numpy()` for conversion to a numpy " + "array instead.", + FutureWarning, + stacklevel=2, + ) arr = self._values.ravel(order=order) if isinstance(arr, np.ndarray) and using_copy_on_write(): arr.flags.writeable = False diff --git a/pandas/tests/copy_view/test_array.py b/pandas/tests/copy_view/test_array.py index 62a6a3374e612..e5d0aafb80b35 100644 --- a/pandas/tests/copy_view/test_array.py +++ b/pandas/tests/copy_view/test_array.py @@ -116,7 +116,8 @@ def test_series_to_numpy(using_copy_on_write): @pytest.mark.parametrize("order", ["F", "C"]) def test_ravel_read_only(using_copy_on_write, order): ser = Series([1, 2, 3]) - arr = ser.ravel(order=order) + with tm.assert_produces_warning(FutureWarning, match="is deprecated"): + arr = ser.ravel(order=order) if using_copy_on_write: assert arr.flags.writeable is False assert np.shares_memory(get_array(ser), arr) diff --git a/pandas/tests/dtypes/cast/test_downcast.py b/pandas/tests/dtypes/cast/test_downcast.py index c01eac746455c..9430ba2c478ae 100644 --- a/pandas/tests/dtypes/cast/test_downcast.py +++ b/pandas/tests/dtypes/cast/test_downcast.py @@ -56,8 +56,8 @@ def test_downcast_booleans(): ser = Series([True, True, False]) result = maybe_downcast_to_dtype(ser, np.dtype(np.float64)) - expected = ser - tm.assert_series_equal(result, expected) + expected = ser.values + tm.assert_numpy_array_equal(result, expected) def test_downcast_conversion_no_nan(any_real_numpy_dtype): diff --git a/pandas/tests/series/test_api.py b/pandas/tests/series/test_api.py index c29fe6ba06ab4..9d69321ff7dbb 100644 --- a/pandas/tests/series/test_api.py +++ b/pandas/tests/series/test_api.py @@ -140,7 +140,9 @@ def test_ndarray_compat_like_func(self): def test_ndarray_compat_ravel(self): # ravel s = Series(np.random.default_rng(2).standard_normal(10)) - tm.assert_almost_equal(s.ravel(order="F"), s.values.ravel(order="F")) + with tm.assert_produces_warning(FutureWarning, match="ravel is deprecated"): + result = s.ravel(order="F") + tm.assert_almost_equal(result, s.values.ravel(order="F")) def test_empty_method(self): s_empty = Series(dtype=object)