Skip to content

Commit 56f03c7

Browse files
authored
ENH: DataFrame __divmod__, __rdivmod__ (#37165)
1 parent 7f910b5 commit 56f03c7

File tree

3 files changed

+19
-9
lines changed

3 files changed

+19
-9
lines changed

doc/source/whatsnew/v1.2.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ Other enhancements
194194
- Added :meth:`Rolling.sem()` and :meth:`Expanding.sem()` to compute the standard error of mean (:issue:`26476`).
195195
- :meth:`Rolling.var()` and :meth:`Rolling.std()` use Kahan summation and Welfords Method to avoid numerical issues (:issue:`37051`)
196196
- :meth:`DataFrame.plot` now recognizes ``xlabel`` and ``ylabel`` arguments for plots of type ``scatter`` and ``hexbin`` (:issue:`37001`)
197+
- :class:`DataFrame` now supports ``divmod`` operation (:issue:`37165`)
197198

198199
.. _whatsnew_120.api_breaking.python:
199200

pandas/core/frame.py

+12
Original file line numberDiff line numberDiff line change
@@ -5958,6 +5958,18 @@ def _construct_result(self, result) -> DataFrame:
59585958
out.index = self.index
59595959
return out
59605960

5961+
def __divmod__(self, other) -> Tuple[DataFrame, DataFrame]:
5962+
# Naive implementation, room for optimization
5963+
div = self // other
5964+
mod = self - div * other
5965+
return div, mod
5966+
5967+
def __rdivmod__(self, other) -> Tuple[DataFrame, DataFrame]:
5968+
# Naive implementation, room for optimization
5969+
div = other // self
5970+
mod = other - div * self
5971+
return div, mod
5972+
59615973
# ----------------------------------------------------------------------
59625974
# Combination-Related
59635975

pandas/tests/arithmetic/test_timedelta64.py

+6-9
Original file line numberDiff line numberDiff line change
@@ -1900,10 +1900,13 @@ def test_td64arr_mod_tdscalar(self, box_with_array, three_days):
19001900
result = tdarr % three_days
19011901
tm.assert_equal(result, expected)
19021902

1903-
if box_with_array is pd.DataFrame:
1904-
pytest.xfail("DataFrame does not have __divmod__ or __rdivmod__")
1903+
warn = None
1904+
if box_with_array is pd.DataFrame and isinstance(three_days, pd.DateOffset):
1905+
warn = PerformanceWarning
1906+
1907+
with tm.assert_produces_warning(warn):
1908+
result = divmod(tdarr, three_days)
19051909

1906-
result = divmod(tdarr, three_days)
19071910
tm.assert_equal(result[1], expected)
19081911
tm.assert_equal(result[0], tdarr // three_days)
19091912

@@ -1921,9 +1924,6 @@ def test_td64arr_mod_int(self, box_with_array):
19211924
with pytest.raises(TypeError, match=msg):
19221925
2 % tdarr
19231926

1924-
if box_with_array is pd.DataFrame:
1925-
pytest.xfail("DataFrame does not have __divmod__ or __rdivmod__")
1926-
19271927
result = divmod(tdarr, 2)
19281928
tm.assert_equal(result[1], expected)
19291929
tm.assert_equal(result[0], tdarr // 2)
@@ -1939,9 +1939,6 @@ def test_td64arr_rmod_tdscalar(self, box_with_array, three_days):
19391939
result = three_days % tdarr
19401940
tm.assert_equal(result, expected)
19411941

1942-
if box_with_array is pd.DataFrame:
1943-
pytest.xfail("DataFrame does not have __divmod__ or __rdivmod__")
1944-
19451942
result = divmod(three_days, tdarr)
19461943
tm.assert_equal(result[1], expected)
19471944
tm.assert_equal(result[0], three_days // tdarr)

0 commit comments

Comments
 (0)