Skip to content

Deprecate combineAdd and combineMult (GH10735) #10812

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

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions doc/source/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -799,9 +799,7 @@ Binary operator functions
DataFrame.ne
DataFrame.eq
DataFrame.combine
DataFrame.combineAdd
DataFrame.combine_first
DataFrame.combineMult

Function application, GroupBy
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand Down
8 changes: 6 additions & 2 deletions doc/source/whatsnew/v0.17.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -532,7 +532,11 @@ Deprecations
===================== =================================

- ``Categorical.name`` was deprecated to make ``Categorical`` more ``numpy.ndarray`` like. Use ``Series(cat, name="whatever")`` instead (:issue:`10482`).
- ``drop_duplicates`` and ``duplicated``'s ``take_last`` keyword was removed in favor of ``keep``. (:issue:`6511`, :issue:`8505`)
- ``drop_duplicates`` and ``duplicated``'s ``take_last`` keyword was deprecated in favor of ``keep``. (:issue:`6511`, :issue:`8505`)
- ``DataFrame.combineAdd`` and ``DataFrame.combineMult`` are deprecated. They
Copy link
Contributor

Choose a reason for hiding this comment

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

need issue number

can easily be replaced by using the ``add`` and ``mul`` methods:
``DataFrame.add(other, fill_value=0)`` and ``DataFrame.mul(other, fill_value=1.)``
(:issue:`10735`).

.. _whatsnew_0170.prior_deprecations:

Expand Down Expand Up @@ -633,5 +637,5 @@ Bug Fixes
- Bug in ``pd.DataFrame`` when constructing an empty DataFrame with a string dtype (:issue:`9428`)
- Bug in ``pd.unique`` for arrays with the ``datetime64`` or ``timedelta64`` dtype that meant an array with object dtype was returned instead the original dtype (:issue: `9431`)
- Bug in ``DatetimeIndex.take`` and ``TimedeltaIndex.take`` may not raise ``IndexError`` against invalid index (:issue:`10295`)
- Bug in ``Series([np.nan]).astype('M8[ms]')``, which now returns ``Series([pd.NaT])`` (:issue:`10747`)
- Bug in ``Series([np.nan]).astype('M8[ms]')``, which now returns ``Series([pd.NaT])`` (:issue:`10747`)
- Bug in ``PeriodIndex.order`` reset freq (:issue:`10295`)
20 changes: 20 additions & 0 deletions pandas/core/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -4900,6 +4900,8 @@ def isin(self, values):

def combineAdd(self, other):
"""
DEPRECATED. Use ``DataFrame.add(other, fill_value=0.)`` instead.

Add two DataFrame objects and do not propagate
NaN values, so if for a (column, time) one frame is missing a
value, it will default to the other frame's value (which might
Expand All @@ -4912,11 +4914,21 @@ def combineAdd(self, other):
Returns
-------
DataFrame

See also
--------
DataFrame.add

"""
warnings.warn("'combineAdd' is deprecated. Use "
"'DataFrame.add(other, fill_value=0.)' instead",
FutureWarning, stacklevel=2)
return self.add(other, fill_value=0.)

def combineMult(self, other):
"""
DEPRECATED. Use ``DataFrame.mul(other, fill_value=1.)`` instead.

Multiply two DataFrame objects and do not propagate NaN values, so if
for a (column, time) one frame is missing a value, it will default to
the other frame's value (which might be NaN as well)
Expand All @@ -4928,7 +4940,15 @@ def combineMult(self, other):
Returns
-------
DataFrame

See also
--------
DataFrame.mul

"""
warnings.warn("'combineMult' is deprecated. Use "
"'DataFrame.mul(other, fill_value=1.)' instead",
FutureWarning, stacklevel=2)
return self.mul(other, fill_value=1.)


Expand Down
98 changes: 51 additions & 47 deletions pandas/tests/test_frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -11787,61 +11787,65 @@ def test_update_from_non_df(self):
assert_frame_equal(df, expected)

def test_combineAdd(self):
# trivial
comb = self.frame.combineAdd(self.frame)
assert_frame_equal(comb, self.frame * 2)

# more rigorous
a = DataFrame([[1., nan, nan, 2., nan]],
columns=np.arange(5))
b = DataFrame([[2., 3., nan, 2., 6., nan]],
columns=np.arange(6))
expected = DataFrame([[3., 3., nan, 4., 6., nan]],
columns=np.arange(6))

result = a.combineAdd(b)
assert_frame_equal(result, expected)
result2 = a.T.combineAdd(b.T)
assert_frame_equal(result2, expected.T)

expected2 = a.combine(b, operator.add, fill_value=0.)
assert_frame_equal(expected, expected2)

# corner cases
comb = self.frame.combineAdd(self.empty)
assert_frame_equal(comb, self.frame)

comb = self.empty.combineAdd(self.frame)
assert_frame_equal(comb, self.frame)

# integer corner case
df1 = DataFrame({'x': [5]})
df2 = DataFrame({'x': [1]})
df3 = DataFrame({'x': [6]})
comb = df1.combineAdd(df2)
assert_frame_equal(comb, df3)

# mixed type GH2191
df1 = DataFrame({'A': [1, 2], 'B': [3, 4]})
df2 = DataFrame({'A': [1, 2], 'C': [5, 6]})
rs = df1.combineAdd(df2)
xp = DataFrame({'A': [2, 4], 'B': [3, 4.], 'C': [5, 6.]})
assert_frame_equal(xp, rs)
with tm.assert_produces_warning(FutureWarning):
# trivial
comb = self.frame.combineAdd(self.frame)
assert_frame_equal(comb, self.frame * 2)

# more rigorous
a = DataFrame([[1., nan, nan, 2., nan]],
columns=np.arange(5))
b = DataFrame([[2., 3., nan, 2., 6., nan]],
columns=np.arange(6))
expected = DataFrame([[3., 3., nan, 4., 6., nan]],
columns=np.arange(6))

result = a.combineAdd(b)
assert_frame_equal(result, expected)
result2 = a.T.combineAdd(b.T)
assert_frame_equal(result2, expected.T)

expected2 = a.combine(b, operator.add, fill_value=0.)
assert_frame_equal(expected, expected2)

# corner cases
comb = self.frame.combineAdd(self.empty)
assert_frame_equal(comb, self.frame)

comb = self.empty.combineAdd(self.frame)
assert_frame_equal(comb, self.frame)

# integer corner case
df1 = DataFrame({'x': [5]})
df2 = DataFrame({'x': [1]})
df3 = DataFrame({'x': [6]})
comb = df1.combineAdd(df2)
assert_frame_equal(comb, df3)

# mixed type GH2191
df1 = DataFrame({'A': [1, 2], 'B': [3, 4]})
df2 = DataFrame({'A': [1, 2], 'C': [5, 6]})
rs = df1.combineAdd(df2)
xp = DataFrame({'A': [2, 4], 'B': [3, 4.], 'C': [5, 6.]})
assert_frame_equal(xp, rs)

# TODO: test integer fill corner?

def test_combineMult(self):
# trivial
comb = self.frame.combineMult(self.frame)

assert_frame_equal(comb, self.frame ** 2)
with tm.assert_produces_warning(FutureWarning):
# trivial
comb = self.frame.combineMult(self.frame)

# corner cases
comb = self.frame.combineMult(self.empty)
assert_frame_equal(comb, self.frame)
assert_frame_equal(comb, self.frame ** 2)

comb = self.empty.combineMult(self.frame)
assert_frame_equal(comb, self.frame)
# corner cases
comb = self.frame.combineMult(self.empty)
assert_frame_equal(comb, self.frame)

comb = self.empty.combineMult(self.frame)
assert_frame_equal(comb, self.frame)

def test_combine_generic(self):
df1 = self.frame
Expand Down