Skip to content

Commit db2c641

Browse files
committed
Fix _binop for operators which has more than one returns (divmod).
Signed-off-by: HE, Tao <[email protected]>
1 parent 74a9ae3 commit db2c641

File tree

3 files changed

+31
-6
lines changed

3 files changed

+31
-6
lines changed

doc/source/whatsnew/v0.24.2.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ Fixed Regressions
3131
- Fixed regression in ``IntervalDtype`` construction where passing an incorrect string with 'Interval' as a prefix could result in a ``RecursionError``. (:issue:`25338`)
3232
- Fixed regression in :class:`Categorical`, where constructing it from a categorical ``Series`` and an explicit ``categories=`` that differed from that in the ``Series`` created an invalid object which could trigger segfaults. (:issue:`25318`)
3333
- Fixed pip installing from source into an environment without NumPy (:issue:`25193`)
34+
- Fixed bug in :meth:`Series._binop` to handle binary operators that returns more than one :class:`Series` correctly (:issue:`25557`)
3435

3536
.. _whatsnew_0242.enhancements:
3637

pandas/core/series.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2502,6 +2502,15 @@ def _binop(self, other, func, level=None, fill_value=None):
25022502
-------
25032503
Series
25042504
"""
2505+
2506+
def mk_ret(result, new_index, name):
2507+
ret = self._constructor(result, index=new_index, name=name)
2508+
ret.__finalize__(self)
2509+
if name is None:
2510+
# When name is None, __finalize__ overwrites current name
2511+
ret.name = None
2512+
return ret
2513+
25052514
if not isinstance(other, Series):
25062515
raise AssertionError('Other operand must be Series')
25072516

@@ -2519,12 +2528,13 @@ def _binop(self, other, func, level=None, fill_value=None):
25192528
with np.errstate(all='ignore'):
25202529
result = func(this_vals, other_vals)
25212530
name = ops.get_op_result_name(self, other)
2522-
result = self._constructor(result, index=new_index, name=name)
2523-
result = result.__finalize__(self)
2524-
if name is None:
2525-
# When name is None, __finalize__ overwrites current name
2526-
result.name = None
2527-
return result
2531+
if isinstance(result, tuple):
2532+
final_result = ()
2533+
for r in result:
2534+
final_result = (*final_result, mk_ret(r, new_index, name))
2535+
else:
2536+
final_result = mk_ret(result, new_index, name)
2537+
return final_result
25282538

25292539
def combine(self, other, func, fill_value=None):
25302540
"""

pandas/tests/series/test_operators.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,20 @@ def test_op_duplicate_index(self):
741741
expected = pd.Series([11, 12, np.nan], index=[1, 1, 2])
742742
assert_series_equal(result, expected)
743743

744+
def test_divmod(self):
745+
a = Series([1, 1, 1, np.nan], index=['a', 'b', 'c', 'd'])
746+
b = Series([2, np.nan, 1, np.nan], index=['a', 'b', 'd', 'e'])
747+
748+
r1 = divmod(a, b)
749+
r2 = a.divmod(b)
750+
assert_series_equal(r1[0], r2[0])
751+
assert_series_equal(r1[1], r2[1])
752+
753+
r3 = divmod(b, a)
754+
r4 = a.rdivmod(b)
755+
assert_series_equal(r3[0], r4[0])
756+
assert_series_equal(r3[1], r4[1])
757+
744758

745759
class TestSeriesUnaryOps(object):
746760
# __neg__, __pos__, __inv__

0 commit comments

Comments
 (0)