Skip to content

Commit 5f21e82

Browse files
committed
Fix Series divmod pandas-dev#26987
1 parent 989f912 commit 5f21e82

File tree

3 files changed

+61
-0
lines changed

3 files changed

+61
-0
lines changed

pandas/core/missing.py

+20
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,26 @@ def fill_zeros(result, x, y, name, fill):
520520
521521
Mask the nan's from x.
522522
"""
523+
if name == '__divmod__' and isinstance(result, tuple):
524+
# GH#26987; sometimes we don't have a tuple when called
525+
# from dispatch_missing
526+
res1 = fill_zeros(result[0], x, y, '__floordiv__', fill)
527+
res2 = fill_zeros(result[1], x, y, '__mod__', fill)
528+
mask = np.isinf(res1) & np.isinf(res2)
529+
if mask.any():
530+
res2[mask] = np.nan
531+
return res1, res2
532+
533+
elif name == '__rdivmod__':
534+
# GH#26987; sometimes we don't have a tuple when called
535+
# from dispatch_missing
536+
res1 = fill_zeros(result[0], x, y, '__rfloordiv__', fill)
537+
res2 = fill_zeros(result[1], x, y, '__rmod__', fill)
538+
mask = np.isinf(res1) & np.isinf(res2)
539+
if mask.any():
540+
res2[mask] = np.nan
541+
return res1, res2
542+
523543
if fill is None or is_float_dtype(result):
524544
return result
525545

pandas/core/ops.py

+5
Original file line numberDiff line numberDiff line change
@@ -1709,6 +1709,11 @@ def wrapper(left, right):
17091709
rvalues = right
17101710
if isinstance(rvalues, ABCSeries):
17111711
rvalues = rvalues.values
1712+
elif (isinstance(rvalues, ABCIndexClass)
1713+
and rvalues.dtype.kind in 'fciu'):
1714+
# TOOD: We should do this unpacking unconditionally, but ATM doing
1715+
# so breaks on DatetimeArray because it lacks ravel()
1716+
rvalues = rvalues._values
17121717

17131718
with np.errstate(all='ignore'):
17141719
result = na_op(lvalues, rvalues)

pandas/tests/arithmetic/test_numeric.py

+36
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,42 @@ def test_ser_div_ser(self, dtype1, dtype2):
250250
tm.assert_series_equal(result, expected)
251251
assert not result.equals(second / first)
252252

253+
@pytest.mark.parametrize('dtype2', [
254+
np.int64, np.int32, np.int16, np.int8,
255+
np.float64, np.float32, np.float16,
256+
np.uint64, np.uint32, np.uint16, np.uint8])
257+
@pytest.mark.parametrize('dtype1', [np.int64, np.float64, np.uint64])
258+
def test_ser_divmod_zero(self, dtype1, dtype2):
259+
# GH#26987
260+
left = pd.Series([1, 1]).astype(dtype1)
261+
right = pd.Series([0, 2]).astype(dtype2)
262+
263+
expected = left // right, left % right
264+
result = divmod(left, right)
265+
266+
tm.assert_series_equal(result[0], expected[0])
267+
tm.assert_series_equal(result[1], expected[1])
268+
269+
# rdivmod case
270+
result = divmod(left.values, right)
271+
tm.assert_series_equal(result[0], expected[0])
272+
tm.assert_series_equal(result[1], expected[1])
273+
274+
def test_ser_divmod_inf(self):
275+
left = pd.Series([np.inf, 1.])
276+
right = pd.Series([np.inf, 2.])
277+
278+
expected = left // right, left % right
279+
result = divmod(left, right)
280+
281+
tm.assert_series_equal(result[0], expected[0])
282+
tm.assert_series_equal(result[1], expected[1])
283+
284+
# rdivmod case
285+
result = divmod(left.values, right)
286+
tm.assert_series_equal(result[0], expected[0])
287+
tm.assert_series_equal(result[1], expected[1])
288+
253289
def test_rdiv_zero_compat(self):
254290
# GH#8674
255291
zero_array = np.array([0] * 5)

0 commit comments

Comments
 (0)