Skip to content

Commit 3d5e65d

Browse files
authored
BUG: Fix inconsistent ordering between left and right in merge (#37406)
1 parent fb2bd10 commit 3d5e65d

File tree

3 files changed

+17
-7
lines changed

3 files changed

+17
-7
lines changed

doc/source/whatsnew/v1.2.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,7 @@ Reshaping
718718
- Fixed regression in :func:`merge` on merging DatetimeIndex with empty DataFrame (:issue:`36895`)
719719
- Bug in :meth:`DataFrame.apply` not setting index of return value when ``func`` return type is ``dict`` (:issue:`37544`)
720720
- Bug in :func:`concat` resulting in a ``ValueError`` when at least one of both inputs had a non-unique index (:issue:`36263`)
721+
- Bug in :meth:`DataFrame.merge` and :meth:`pandas.merge` returning inconsistent ordering in result for ``how=right`` and ``how=left`` (:issue:`35382`)
721722

722723
Sparse
723724
^^^^^^

pandas/core/reshape/merge.py

+4-7
Original file line numberDiff line numberDiff line change
@@ -1358,12 +1358,14 @@ def get_join_indexers(
13581358
lkey, rkey, count = _factorize_keys(lkey, rkey, sort=sort, how=how)
13591359
# preserve left frame order if how == 'left' and sort == False
13601360
kwargs = copy.copy(kwargs)
1361-
if how == "left":
1361+
if how in ("left", "right"):
13621362
kwargs["sort"] = sort
13631363
join_func = {
13641364
"inner": libjoin.inner_join,
13651365
"left": libjoin.left_outer_join,
1366-
"right": _right_outer_join,
1366+
"right": lambda x, y, count, **kwargs: libjoin.left_outer_join(
1367+
y, x, count, **kwargs
1368+
)[::-1],
13671369
"outer": libjoin.full_outer_join,
13681370
}[how]
13691371

@@ -1883,11 +1885,6 @@ def _left_join_on_index(left_ax: Index, right_ax: Index, join_keys, sort: bool =
18831885
return left_ax, None, right_indexer
18841886

18851887

1886-
def _right_outer_join(x, y, max_groups):
1887-
right_indexer, left_indexer = libjoin.left_outer_join(y, x, max_groups)
1888-
return left_indexer, right_indexer
1889-
1890-
18911888
def _factorize_keys(
18921889
lk: ArrayLike, rk: ArrayLike, sort: bool = True, how: str = "inner"
18931890
) -> Tuple[np.ndarray, np.ndarray, int]:

pandas/tests/reshape/merge/test_merge.py

+12
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,18 @@ def test_merge_nosort(self):
601601

602602
assert (df.var3.unique() == result.var3.unique()).all()
603603

604+
@pytest.mark.parametrize(
605+
("sort", "values"), [(False, [1, 1, 0, 1, 1]), (True, [0, 1, 1, 1, 1])]
606+
)
607+
@pytest.mark.parametrize("how", ["left", "right"])
608+
def test_merge_same_order_left_right(self, sort, values, how):
609+
# GH#35382
610+
df = DataFrame({"a": [1, 0, 1]})
611+
612+
result = df.merge(df, on="a", how=how, sort=sort)
613+
expected = DataFrame(values, columns=["a"])
614+
tm.assert_frame_equal(result, expected)
615+
604616
def test_merge_nan_right(self):
605617
df1 = DataFrame({"i1": [0, 1], "i2": [0, 1]})
606618
df2 = DataFrame({"i1": [0], "i3": [0]})

0 commit comments

Comments
 (0)