diff --git a/pandas/core/series.py b/pandas/core/series.py index 74dcdaee327da..ce2fa6ceb6f50 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -3872,7 +3872,7 @@ def transform(self, func, axis=0, *args, **kwargs): self._get_axis_number(axis) return super().transform(func, *args, **kwargs) - def apply(self, func, convert_dtype=True, args=(), **kwds): + def apply(self, func, convert_dtype=True, force_mapping=False, args=(), **kwds): """ Invoke function on values of Series. @@ -3886,6 +3886,9 @@ def apply(self, func, convert_dtype=True, args=(), **kwds): convert_dtype : bool, default True Try to find better dtype for elementwise function results. If False, leave as dtype=object. + force_mapping : bool, default False + If set to True, forces func to be called on each element separately. + Useful when using numpy functions. args : tuple Positional arguments passed to func after the series value. **kwds @@ -3992,9 +3995,8 @@ def f(x): f = func with np.errstate(all="ignore"): - if isinstance(f, np.ufunc): + if not force_mapping and isinstance(f, np.ufunc): return f(self) - # row-wise access if is_extension_array_dtype(self.dtype) and hasattr(self._values, "map"): # GH#23179 some EAs do not have `map` diff --git a/pandas/tests/series/test_apply.py b/pandas/tests/series/test_apply.py index 589f8933efa96..3ea35e748d526 100644 --- a/pandas/tests/series/test_apply.py +++ b/pandas/tests/series/test_apply.py @@ -813,3 +813,11 @@ def test_apply_to_timedelta(self): b = Series(list_of_strings).apply(pd.to_timedelta) # noqa # Can't compare until apply on a Series gives the correct dtype # assert_series_equal(a, b) + + def test_apply_to_numpy_func_with_force_mapping(self): + s = pd.Series([np.array([0.1, 0.2], dtype=float)]) + expected = pd.Series( + [np.array([0.09983341664682815, 0.19866933079506122], dtype=float)] + ) + result = s.apply(np.sin, force_mapping=True) + tm.assert_series_equal(result, expected)