Skip to content

Unary plus operator (Issue #16073) #16106

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

Closed
wants to merge 10 commits into from
5 changes: 3 additions & 2 deletions doc/source/whatsnew/v0.20.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,7 @@ See :ref:`the docs here <io.pickle.compression>`

Using an explicit compression type

.. ipython:: python
Copy link
Contributor

Choose a reason for hiding this comment

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

don't change other things in the file

Copy link
Author

Choose a reason for hiding this comment

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

I'm not certain why this happened. The rest of the diff shows that the same identical line is added again, thus making no actual changes to the file


.. ipython:: python
df.to_pickle("data.pkl.compress", compression="gzip")
rt = pd.read_pickle("data.pkl.compress", compression="gzip")
rt
Expand Down Expand Up @@ -1196,6 +1195,8 @@ Other API Changes
- ``DataFrame`` and ``Panel`` constructors with invalid input will now raise ``ValueError`` rather than ``pandas.core.common.PandasError``, if called with scalar inputs and not axes; The exception ``PandasError`` is removed as well. (:issue:`15541`)
- The exception ``pandas.core.common.AmbiguousIndexError`` is removed as it is not referenced (:issue:`15541`)

- ``Series`` and ``DataFrame`` now have unary plus operators (:issue:`16073`). The plus operator behaves consistently with the unary minus operator.


.. _whatsnew_0200.privacy:

Expand Down
13 changes: 13 additions & 0 deletions pandas/core/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -859,6 +859,19 @@ def _indexed_same(self, other):
return all([self._get_axis(a).equals(other._get_axis(a))
for a in self._AXIS_ORDERS])

def __pos__(self):
values = _values_from_object(self)
if values.dtype == np.bool_:
Copy link
Contributor

Choose a reason for hiding this comment

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

something like:

if is_bool_dtype(values):
   ...
elif not (is_numeric_dtype(values) or is_timedelta64_dtype(values)):
   raise

Copy link
Contributor

Choose a reason for hiding this comment

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

add the same logic to __neg__

arr = values
else:
if (len(values) > 0):
try:
-values[0]
except TypeError:
raise TypeError("`+` only works on data types that support `-`")
arr = operator.pos(values)
return self.__array_wrap__(arr)

def __neg__(self):
values = _values_from_object(self)
if values.dtype == np.bool_:
Expand Down
10 changes: 8 additions & 2 deletions pandas/tests/frame/test_operators.py
Original file line number Diff line number Diff line change
Expand Up @@ -343,9 +343,15 @@ def test_logical_with_nas(self):
expected = Series([True, True])
assert_series_equal(result, expected)

def test_pos(self):
try:
assert_frame_equal(+self.frame, self.frame.apply(lambda x: +self.frame))
Copy link
Contributor

Choose a reason for hiding this comment

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

dont' test like this. instead use a couple of sample frames that have singular dtypes (can be a single column). test the valid ones via assert_frame_equal(-frame, -1 * frame). The invalid ones should raise.

except TypeError:
if not (len(self.frame) > 0 and isinstance(self.frame[0], pd.Timestamp)):
raise

def test_neg(self):
# what to do?
assert_frame_equal(-self.frame, -1 * self.frame)
assert_frame_equal(-self.frame, self.frame.apply(lambda x: -self.frame))

def test_invert(self):
assert_frame_equal(-(self.frame < 0), ~(self.frame < 0))
Expand Down
9 changes: 8 additions & 1 deletion pandas/tests/series/test_operators.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,15 @@ def check(series, other, check_reverse=False):
check(self.ts, 5, check_reverse=True)
check(tm.makeFloatSeries(), tm.makeFloatSeries(), check_reverse=True)

def test_pos(self):
try:
assert_series_equal(+self.series, self.series.apply(lambda x: +x))
except TypeError:
if not (len(self.frame) > 0 and isinstance(self.frame[0], pd.Timestampe)):
Copy link
Contributor

Choose a reason for hiding this comment

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

same

raise

def test_neg(self):
assert_series_equal(-self.series, -1 * self.series)
assert_series_equal(-self.series, self.series.apply(lambda x: -x))

def test_invert(self):
assert_series_equal(-(self.series < 0), ~(self.series < 0))
Expand Down