Skip to content

DEPR: Deprecate ravel #56053

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
Nov 27, 2023
1 change: 1 addition & 0 deletions doc/source/whatsnew/v2.2.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,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`, use ``np.ravel`` instead (:issue:`52511`)
- Deprecated ``year``, ``month``, ``quarter``, ``day``, ``hour``, ``minute``, and ``second`` keywords in the :class:`PeriodIndex` constructor, use :meth:`PeriodIndex.from_fields` instead (:issue:`55960`)
- Deprecated allowing non-keyword arguments in :meth:`DataFrame.to_clipboard`. (:issue:`54229`)
- Deprecated allowing non-keyword arguments in :meth:`DataFrame.to_csv` except ``path_or_buf``. (:issue:`54229`)
Expand Down
2 changes: 2 additions & 0 deletions pandas/_testing/asserters.py
Original file line number Diff line number Diff line change
Expand Up @@ -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, "
Expand Down
8 changes: 5 additions & 3 deletions pandas/core/reshape/pivot.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,15 +309,17 @@ def _add_margins(

row_names = result.index.names
# check the result column and leave floats

def _cast_types(x, dtype):
return maybe_downcast_to_dtype(x._values, dtype)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we do that inside maybe_downcast_to_dtype instead? That function is also used in some other places (I don't know if it is guaranteed to be called with a non-Series in those other places, but our test coverage might also be lacking on that aspect)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure


for dtype in set(result.dtypes):
if isinstance(dtype, ExtensionDtype):
# Can hold NA already
continue

cols = result.select_dtypes([dtype]).columns
margin_dummy[cols] = margin_dummy[cols].apply(
maybe_downcast_to_dtype, args=(dtype,)
)
margin_dummy[cols] = margin_dummy[cols].apply(_cast_types, args=(dtype,))
result = result._append(margin_dummy)
result.index.names = row_names

Expand Down
7 changes: 6 additions & 1 deletion pandas/core/series.py
Original file line number Diff line number Diff line change
Expand Up @@ -858,9 +858,14 @@ 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. Use numpy.ravel directly.",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or maybe we should also point to to_numpy() in case people use this to essentially get the numpy series (the "ravel" aspect never does something, since Series is already 1D)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or just "dont do it bc it isnt necessary"? (also should we deprecate Index.ravel?)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes and yes

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or just "dont do it bc it isnt necessary"?

That's not necessarily correct. If you rely on the current return value, i.e. if your code requires that the object is a 1D numpy array, and you currently use ravel for that, you do need to replace ravel with a conversion to numpy.
(and that's actually how we were implicitly using it internally)

FutureWarning,
stacklevel=find_stack_level(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
stacklevel=find_stack_level(),
stacklevel=2,

For a simple case like this where the warning is directly raised in the top-level method, I prefer setting it explicitly, which avoids potential hickups with the function (I think we had perf issues in certain cases, and this also avoids getting a wrong stacklevel in case we forget a use case of ravel in our own code base)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure

)
arr = self._values.ravel(order=order)
if isinstance(arr, np.ndarray) and using_copy_on_write():
arr.flags.writeable = False
Expand Down
3 changes: 2 additions & 1 deletion pandas/tests/copy_view/test_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 3 additions & 1 deletion pandas/tests/series/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down