Skip to content

Commit 8cb6be0

Browse files
jorisvandenbosschejreback
authored andcommitted
API/REGR: (re-)allow neg/pos unary operation on object dtype (#21590)
1 parent c45bb0b commit 8cb6be0

File tree

3 files changed

+27
-2
lines changed

3 files changed

+27
-2
lines changed

Diff for: doc/source/whatsnew/v0.23.2.txt

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ Fixed Regressions
5454

5555
- Fixed regression in :meth:`to_csv` when handling file-like object incorrectly (:issue:`21471`)
5656
- Bug in both :meth:`DataFrame.first_valid_index` and :meth:`Series.first_valid_index` raised for a row index having duplicate values (:issue:`21441`)
57+
- Fixed regression in unary negative operations with object dtype (:issue:`21380`)
5758
- Bug in :meth:`Timestamp.ceil` and :meth:`Timestamp.floor` when timestamp is a multiple of the rounding frequency (:issue:`21262`)
5859

5960
.. _whatsnew_0232.performance:

Diff for: pandas/core/generic.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
is_dict_like,
2828
is_re_compilable,
2929
is_period_arraylike,
30+
is_object_dtype,
3031
pandas_dtype)
3132
from pandas.core.dtypes.cast import maybe_promote, maybe_upcast_putmask
3233
from pandas.core.dtypes.inference import is_hashable
@@ -1117,7 +1118,8 @@ def __neg__(self):
11171118
values = com._values_from_object(self)
11181119
if is_bool_dtype(values):
11191120
arr = operator.inv(values)
1120-
elif (is_numeric_dtype(values) or is_timedelta64_dtype(values)):
1121+
elif (is_numeric_dtype(values) or is_timedelta64_dtype(values)
1122+
or is_object_dtype(values)):
11211123
arr = operator.neg(values)
11221124
else:
11231125
raise TypeError("Unary negative expects numeric dtype, not {}"
@@ -1128,7 +1130,8 @@ def __pos__(self):
11281130
values = com._values_from_object(self)
11291131
if (is_bool_dtype(values) or is_period_arraylike(values)):
11301132
arr = values
1131-
elif (is_numeric_dtype(values) or is_timedelta64_dtype(values)):
1133+
elif (is_numeric_dtype(values) or is_timedelta64_dtype(values)
1134+
or is_object_dtype(values)):
11321135
arr = operator.pos(values)
11331136
else:
11341137
raise TypeError("Unary plus expects numeric dtype, not {}"

Diff for: pandas/tests/frame/test_operators.py

+21
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from __future__ import print_function
44
from collections import deque
55
from datetime import datetime
6+
from decimal import Decimal
67
import operator
78

89
import pytest
@@ -282,6 +283,17 @@ def test_neg_numeric(self, df, expected):
282283
assert_frame_equal(-df, expected)
283284
assert_series_equal(-df['a'], expected['a'])
284285

286+
@pytest.mark.parametrize('df, expected', [
287+
(np.array([1, 2], dtype=object), np.array([-1, -2], dtype=object)),
288+
([Decimal('1.0'), Decimal('2.0')], [Decimal('-1.0'), Decimal('-2.0')]),
289+
])
290+
def test_neg_object(self, df, expected):
291+
# GH 21380
292+
df = pd.DataFrame({'a': df})
293+
expected = pd.DataFrame({'a': expected})
294+
assert_frame_equal(-df, expected)
295+
assert_series_equal(-df['a'], expected['a'])
296+
285297
@pytest.mark.parametrize('df', [
286298
pd.DataFrame({'a': ['a', 'b']}),
287299
pd.DataFrame({'a': pd.to_datetime(['2017-01-22', '1970-01-01'])}),
@@ -307,6 +319,15 @@ def test_pos_numeric(self, df):
307319

308320
@pytest.mark.parametrize('df', [
309321
pd.DataFrame({'a': ['a', 'b']}),
322+
pd.DataFrame({'a': np.array([-1, 2], dtype=object)}),
323+
pd.DataFrame({'a': [Decimal('-1.0'), Decimal('2.0')]}),
324+
])
325+
def test_pos_object(self, df):
326+
# GH 21380
327+
assert_frame_equal(+df, df)
328+
assert_series_equal(+df['a'], df['a'])
329+
330+
@pytest.mark.parametrize('df', [
310331
pd.DataFrame({'a': pd.to_datetime(['2017-01-22', '1970-01-01'])}),
311332
])
312333
def test_pos_raises(self, df):

0 commit comments

Comments
 (0)