diff --git a/doc/source/getting_started/dsintro.rst b/doc/source/getting_started/dsintro.rst index 33e5d390447d7..2fb0b163642c5 100644 --- a/doc/source/getting_started/dsintro.rst +++ b/doc/source/getting_started/dsintro.rst @@ -753,6 +753,11 @@ The ufunc is applied to the underlying array in a Series. ser = pd.Series([1, 2, 3, 4]) np.exp(ser) +.. versionchanged:: 0.25.0 + + When multiple ``Series`` are passed to a ufunc, they are aligned before + performing the operation. + Like other parts of the library, pandas will automatically align labeled inputs as part of a ufunc with multiple inputs. For example, using :meth:`numpy.remainder` on two :class:`Series` with differently ordered labels will align before the operation. diff --git a/doc/source/whatsnew/v0.25.0.rst b/doc/source/whatsnew/v0.25.0.rst index f87a702e1c5b5..ea6a04ac726b7 100644 --- a/doc/source/whatsnew/v0.25.0.rst +++ b/doc/source/whatsnew/v0.25.0.rst @@ -821,6 +821,7 @@ Other deprecations - The :meth:`Series.get_values`, :meth:`DataFrame.get_values`, :meth:`Index.get_values`, :meth:`SparseArray.get_values` and :meth:`Categorical.get_values` methods are deprecated. One of ``np.asarray(..)`` or :meth:`~Series.to_numpy` can be used instead (:issue:`19617`). +- The 'outer' method on NumPy ufuncs, e.g. ``np.subtract.outer`` has been deprecated on :class:`Series` objects. Convert the input to an array with :attr:`Series.array` first (:issue:`27186`) - :meth:`Timedelta.resolution` is deprecated and replaced with :meth:`Timedelta.resolution_string`. In a future version, :meth:`Timedelta.resolution` will be changed to behave like the standard library :attr:`timedelta.resolution` (:issue:`21344`) - :func:`read_table` has been undeprecated. (:issue:`25220`) - :attr:`Index.dtype_str` is deprecated. (:issue:`18262`) diff --git a/pandas/core/series.py b/pandas/core/series.py index f5f9f1ab4f9ab..acae4b0449f72 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -786,6 +786,19 @@ def __array_ufunc__( def construct_return(result): if lib.is_scalar(result): return result + elif result.ndim > 1: + # e.g. np.subtract.outer + if method == 'outer': + msg = ( + "outer method for ufunc {} is not implemented on " + "pandas objects. Returning an ndarray, but in the " + "future this will raise a 'NotImplementedError'. " + "Consider explicitly converting the Series " + "to an array with '.array' first." + ) + warnings.warn(msg.format(ufunc), FutureWarning, + stacklevel=3) + return result return self._constructor(result, index=index, name=name, diff --git a/pandas/tests/series/test_ufunc.py b/pandas/tests/series/test_ufunc.py index 1a0eeb51c4921..183aa6e393355 100644 --- a/pandas/tests/series/test_ufunc.py +++ b/pandas/tests/series/test_ufunc.py @@ -310,3 +310,18 @@ def __repr__(self): result = np.add(s, Thing(1)) expected = pd.Series([Thing(2), Thing(3)]) tm.assert_series_equal(result, expected) + + +def test_outer(): + # https://github.com/pandas-dev/pandas/issues/27186 + s = pd.Series([1, 2, 3]) + o = np.array([1, 2, 3]) + + with tm.assert_produces_warning(FutureWarning): + result = np.subtract.outer(s, o) + expected = np.array([ + [0, -1, -2], + [1, 0, -1], + [2, 1, 0] + ], dtype=np.dtype('int64')) + tm.assert_numpy_array_equal(result, expected)