Skip to content

Commit 3e4f000

Browse files
DEPR: Deprecate outer ufunc in Series.__array_ufunc__ (#27198)
* DEPR: Deprecate outer ufunc in Series.__array_ufunc__ Closes #27186
1 parent 9bee334 commit 3e4f000

File tree

4 files changed

+34
-0
lines changed

4 files changed

+34
-0
lines changed

doc/source/getting_started/dsintro.rst

+5
Original file line numberDiff line numberDiff line change
@@ -753,6 +753,11 @@ The ufunc is applied to the underlying array in a Series.
753753
ser = pd.Series([1, 2, 3, 4])
754754
np.exp(ser)
755755
756+
.. versionchanged:: 0.25.0
757+
758+
When multiple ``Series`` are passed to a ufunc, they are aligned before
759+
performing the operation.
760+
756761
Like other parts of the library, pandas will automatically align labeled inputs
757762
as part of a ufunc with multiple inputs. For example, using :meth:`numpy.remainder`
758763
on two :class:`Series` with differently ordered labels will align before the operation.

doc/source/whatsnew/v0.25.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -821,6 +821,7 @@ Other deprecations
821821
- The :meth:`Series.get_values`, :meth:`DataFrame.get_values`, :meth:`Index.get_values`,
822822
:meth:`SparseArray.get_values` and :meth:`Categorical.get_values` methods are deprecated.
823823
One of ``np.asarray(..)`` or :meth:`~Series.to_numpy` can be used instead (:issue:`19617`).
824+
- 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`)
824825
- :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`)
825826
- :func:`read_table` has been undeprecated. (:issue:`25220`)
826827
- :attr:`Index.dtype_str` is deprecated. (:issue:`18262`)

pandas/core/series.py

+13
Original file line numberDiff line numberDiff line change
@@ -786,6 +786,19 @@ def __array_ufunc__(
786786
def construct_return(result):
787787
if lib.is_scalar(result):
788788
return result
789+
elif result.ndim > 1:
790+
# e.g. np.subtract.outer
791+
if method == 'outer':
792+
msg = (
793+
"outer method for ufunc {} is not implemented on "
794+
"pandas objects. Returning an ndarray, but in the "
795+
"future this will raise a 'NotImplementedError'. "
796+
"Consider explicitly converting the Series "
797+
"to an array with '.array' first."
798+
)
799+
warnings.warn(msg.format(ufunc), FutureWarning,
800+
stacklevel=3)
801+
return result
789802
return self._constructor(result,
790803
index=index,
791804
name=name,

pandas/tests/series/test_ufunc.py

+15
Original file line numberDiff line numberDiff line change
@@ -310,3 +310,18 @@ def __repr__(self):
310310
result = np.add(s, Thing(1))
311311
expected = pd.Series([Thing(2), Thing(3)])
312312
tm.assert_series_equal(result, expected)
313+
314+
315+
def test_outer():
316+
# https://github.com/pandas-dev/pandas/issues/27186
317+
s = pd.Series([1, 2, 3])
318+
o = np.array([1, 2, 3])
319+
320+
with tm.assert_produces_warning(FutureWarning):
321+
result = np.subtract.outer(s, o)
322+
expected = np.array([
323+
[0, -1, -2],
324+
[1, 0, -1],
325+
[2, 1, 0]
326+
], dtype=np.dtype('int64'))
327+
tm.assert_numpy_array_equal(result, expected)

0 commit comments

Comments
 (0)