diff --git a/doc/source/whatsnew/v1.2.0.rst b/doc/source/whatsnew/v1.2.0.rst index ddee06aeab779..ebb8b6dc5a85e 100644 --- a/doc/source/whatsnew/v1.2.0.rst +++ b/doc/source/whatsnew/v1.2.0.rst @@ -434,6 +434,7 @@ Other - Fixed metadata propagation in the :class:`Series.dt` accessor (:issue:`28283`) - Bug in :meth:`Series.transform` would give incorrect results or raise when the argument ``func`` was dictionary (:issue:`35811`) - Bug in :meth:`Index.union` behaving differently depending on whether operand is a :class:`Index` or other list-like (:issue:`36384`) +- Fixed metadata propagation in :meth:`Series.abs` and ufuncs called on Series (:issue:`28283`) .. --------------------------------------------------------------------------- diff --git a/pandas/core/series.py b/pandas/core/series.py index d2c702d924136..ea04125e28a8c 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -746,7 +746,13 @@ def construct_return(result): # GH#27198 raise NotImplementedError return result - return self._constructor(result, index=index, name=name, copy=False) + # TODO: When we support multiple values in __finalize__, this + # should pass alignable as `other` instead of self. + # Then `np.add(a, b)` would consider attrs from both a and b + # when a and b are NDFrames. + return self._constructor( + result, index=index, name=name, copy=False + ).__finalize__(self) if type(result) is tuple: # multiple return values diff --git a/pandas/tests/generic/test_finalize.py b/pandas/tests/generic/test_finalize.py index 6692102bc9008..65b077d088847 100644 --- a/pandas/tests/generic/test_finalize.py +++ b/pandas/tests/generic/test_finalize.py @@ -3,6 +3,7 @@ """ import operator import re +from typing import Any, List, Tuple import numpy as np import pytest @@ -29,7 +30,7 @@ # - Tuple: Constructor args # - Callable: pass the constructed value with attrs set to this. -_all_methods = [ +_all_methods: List[Tuple[Any, Any, Any]] = [ ( pd.Series, (np.array([0], dtype="float64")), @@ -330,7 +331,8 @@ (pd.DataFrame, frame_data, operator.inv), (pd.Series, [1], operator.inv), (pd.DataFrame, frame_data, abs), - pytest.param((pd.Series, [1], abs), marks=not_implemented_mark), + (pd.Series, [1], abs), + (pd.Series, [1], np.arccos), pytest.param((pd.DataFrame, frame_data, round), marks=not_implemented_mark), (pd.Series, [1], round), (pd.DataFrame, frame_data, operator.methodcaller("take", [0, 0])),