Skip to content

Commit 80693b7

Browse files
merge master
1 parent 42b4c97 commit 80693b7

File tree

7 files changed

+18
-60
lines changed

7 files changed

+18
-60
lines changed

doc/source/whatsnew/v0.25.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ Other Enhancements
2121

2222
- Indexing of ``DataFrame`` and ``Series`` now accepts zerodim ``np.ndarray`` (:issue:`24919`)
2323
- :meth:`Timestamp.replace` now supports the ``fold`` argument to disambiguate DST transition times (:issue:`25017`)
24+
- :function:`pandas.merge` now accepts ``None`` as input of suffixes (:issue:`25242`)
2425
- :meth:`DataFrame.at_time` and :meth:`Series.at_time` now support :meth:`datetime.time` objects with timezones (:issue:`24043`)
2526
- ``Series.str`` has gained :meth:`Series.str.casefold` method to removes all case distinctions present in a string (:issue:`25405`)
2627
- :meth:`DataFrame.set_index` now works for instances of ``abc.Iterator``, provided their output is of the same length as the calling frame (:issue:`22484`, :issue:`24984`)

pandas/core/frame.py

-8
Original file line numberDiff line numberDiff line change
@@ -273,14 +273,6 @@
273273
4 bar 2 bar 6
274274
5 baz 3 baz 7
275275
276-
Merge DataFrames df1 and df2, but raise an exception if the DataFrames have
277-
any overlapping columns.
278-
279-
>>> df1.merge(df2, left_on='lkey', right_on='rkey', suffixes=(False, False))
280-
Traceback (most recent call last):
281-
...
282-
ValueError: columns overlap but no suffix specified:
283-
Index(['value'], dtype='object')
284276
"""
285277

286278
# -----------------------------------------------------------------------

pandas/core/internals/managers.py

-3
Original file line numberDiff line numberDiff line change
@@ -1963,9 +1963,6 @@ def items_overlap_with_suffix(left, lsuffix, right, rsuffix):
19631963
if len(to_rename) == 0:
19641964
return left, right
19651965
else:
1966-
if not lsuffix and not rsuffix:
1967-
raise ValueError('columns overlap but no suffix specified: '
1968-
'{rename}'.format(rename=to_rename))
19691966

19701967
def renamer(x, suffix):
19711968
"""Rename the left and right indices.

pandas/core/reshape/merge.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -159,13 +159,13 @@ def merge_ordered(left, right, on=None,
159159
left DataFrame
160160
fill_method : {'ffill', None}, default None
161161
Interpolation method for data
162-
suffixes : Sequence, default is ("_x", "_y")
162+
suffixes : Sequence or None, default is ("_x", "_y")
163163
A length-2 sequence where each element is optionally a string
164164
indicating the suffix to add to overlapping column names in
165165
`left` and `right` respectively. Pass a value of `None` instead
166166
of a string to indicate that the column name from `left` or
167-
`right` should be left as-is, with no suffix. At least one of the
168-
values must not be None.
167+
`right` should be left as-is, with no suffix. `None` means
168+
keep both name of overlapping columns as-is.
169169
170170
.. versionchanged:: 0.25.0
171171
how : {'left', 'right', 'outer', 'inner'}, default 'outer'
@@ -495,6 +495,8 @@ def __init__(self, left, right, how='inner', on=None,
495495

496496
self.copy = copy
497497
self.suffixes = suffixes
498+
if self.suffixes is None:
499+
self.suffixes = (None, None)
498500
self.sort = sort
499501

500502
self.left_index = left_index

pandas/tests/frame/test_join.py

-6
Original file line numberDiff line numberDiff line change
@@ -97,12 +97,6 @@ def test_join_index(frame):
9797
with pytest.raises(ValueError, match='join method'):
9898
f.join(f2, how='foo')
9999

100-
# corner case - overlapping columns
101-
msg = 'columns overlap but no suffix'
102-
for how in ('outer', 'left', 'inner'):
103-
with pytest.raises(ValueError, match=msg):
104-
frame.join(frame, how=how)
105-
106100

107101
def test_join_index_more(frame):
108102
af = frame.loc[:, ['A', 'B']]

pandas/tests/reshape/merge/test_merge.py

+12-34
Original file line numberDiff line numberDiff line change
@@ -1618,7 +1618,18 @@ def test_merge_series(on, left_on, right_on, left_index, right_index, nm):
16181618
("a", "a", dict(suffixes=[None, "_x"]), ["a", "a_x"]),
16191619
(0, 0, dict(suffixes=["_a", None]), ["0_a", 0]),
16201620
("a", "a", dict(), ["a_x", "a_y"]),
1621-
(0, 0, dict(), ["0_x", "0_y"])
1621+
(0, 0, dict(), ["0_x", "0_y"]),
1622+
# accept 2-length None alike suffixes input
1623+
(0, 0, dict(suffixes=[None, None]), [0, 0]),
1624+
(0, 0, dict(suffixes=(None, '')), [0, '0']),
1625+
(0, 0, dict(suffixes=['', '']), ['0', '0']),
1626+
("a", "a", dict(suffixes=[None, None]), ["a", "a"]),
1627+
("a", "a", dict(suffixes=["", None]), ["a", "a"]),
1628+
("a", "a", dict(suffixes=(None, None)), ["a", "a"]),
1629+
("a", "a", dict(suffixes=('', '')), ["a", "a"]),
1630+
# accept None as suffixes
1631+
(0, 0, dict(suffixes=None), [0, 0]),
1632+
("a", "a", dict(suffixes=None), ["a", "a"])
16221633
])
16231634
def test_merge_suffix(col1, col2, kwargs, expected_cols):
16241635
# issue: 24782
@@ -1633,36 +1644,3 @@ def test_merge_suffix(col1, col2, kwargs, expected_cols):
16331644

16341645
result = pd.merge(a, b, left_index=True, right_index=True, **kwargs)
16351646
tm.assert_frame_equal(result, expected)
1636-
1637-
1638-
@pytest.mark.parametrize("col1, col2, suffixes", [
1639-
("a", "a", [None, None]),
1640-
("a", "a", (None, None)),
1641-
("a", "a", ("", None)),
1642-
(0, 0, [None, None]),
1643-
(0, 0, (None, ""))
1644-
])
1645-
def test_merge_suffix_error(col1, col2, suffixes):
1646-
# issue: 24782
1647-
a = pd.DataFrame({col1: [1, 2, 3]})
1648-
b = pd.DataFrame({col2: [3, 4, 5]})
1649-
1650-
# TODO: might reconsider current raise behaviour, see issue 24782
1651-
msg = "columns overlap but no suffix specified"
1652-
with pytest.raises(ValueError, match=msg):
1653-
pd.merge(a, b, left_index=True, right_index=True, suffixes=suffixes)
1654-
1655-
1656-
@pytest.mark.parametrize("col1, col2, suffixes", [
1657-
("a", "a", None),
1658-
(0, 0, None)
1659-
])
1660-
def test_merge_suffix_none_error(col1, col2, suffixes):
1661-
# issue: 24782
1662-
a = pd.DataFrame({col1: [1, 2, 3]})
1663-
b = pd.DataFrame({col2: [3, 4, 5]})
1664-
1665-
# TODO: might reconsider current raise behaviour, see GH24782
1666-
msg = "iterable"
1667-
with pytest.raises(TypeError, match=msg):
1668-
pd.merge(a, b, left_index=True, right_index=True, suffixes=suffixes)

pandas/tests/reshape/merge/test_multi.py

-6
Original file line numberDiff line numberDiff line change
@@ -508,12 +508,6 @@ def test_join_multi_levels(self):
508508
with pytest.raises(ValueError):
509509
household.join(portfolio, how='inner')
510510

511-
portfolio2 = portfolio.copy()
512-
portfolio2.index.set_names(['household_id', 'foo'])
513-
514-
with pytest.raises(ValueError):
515-
portfolio2.join(portfolio, how='inner')
516-
517511
def test_join_multi_levels2(self):
518512

519513
# some more advanced merges

0 commit comments

Comments
 (0)