Skip to content

Commit 904277d

Browse files
Backport PR #42692: Regression in merge_asof raising KeyError when at least one by columnis in index (#42694)
Co-authored-by: Patrick Hoefler <[email protected]>
1 parent d71ca72 commit 904277d

File tree

3 files changed

+68
-10
lines changed

3 files changed

+68
-10
lines changed

doc/source/whatsnew/v1.3.1.rst

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ Fixed regressions
2626
- Regression in :func:`concat` between objects with bool dtype and integer dtype casting to object instead of to integer (:issue:`42092`)
2727
- Bug in :class:`Series` constructor not accepting a ``dask.Array`` (:issue:`38645`)
2828
- Fixed regression for ``SettingWithCopyWarning`` displaying incorrect stacklevel (:issue:`42570`)
29+
- Fixed regression for :func:`merge_asof` raising ``KeyError`` when one of the ``by`` columns is in the index (:issue:`34488`)
2930
- Fixed regression in :func:`to_datetime` returning pd.NaT for inputs that produce duplicated values, when ``cache=True`` (:issue:`42259`)
3031

3132

pandas/core/reshape/merge.py

+20-10
Original file line numberDiff line numberDiff line change
@@ -1775,16 +1775,26 @@ def _validate_specification(self) -> None:
17751775
raise MergeError("missing right_by")
17761776

17771777
# GH#29130 Check that merge keys do not have dtype object
1778-
lo_dtype = (
1779-
self.left[self.left_on[0]].dtype
1780-
if not self.left_index
1781-
else self.left.index.dtype
1782-
)
1783-
ro_dtype = (
1784-
self.right[self.right_on[0]].dtype
1785-
if not self.right_index
1786-
else self.right.index.dtype
1787-
)
1778+
if not self.left_index:
1779+
left_on = self.left_on[0]
1780+
lo_dtype = (
1781+
self.left[left_on].dtype
1782+
if left_on in self.left.columns
1783+
else self.left.index.get_level_values(left_on)
1784+
)
1785+
else:
1786+
lo_dtype = self.left.index.dtype
1787+
1788+
if not self.right_index:
1789+
right_on = self.right_on[0]
1790+
ro_dtype = (
1791+
self.right[right_on].dtype
1792+
if right_on in self.right.columns
1793+
else self.right.index.get_level_values(right_on)
1794+
)
1795+
else:
1796+
ro_dtype = self.right.index.dtype
1797+
17881798
if is_object_dtype(lo_dtype) or is_object_dtype(ro_dtype):
17891799
raise MergeError(
17901800
f"Incompatible merge dtype, {repr(ro_dtype)} and "

pandas/tests/reshape/merge/test_merge_asof.py

+47
Original file line numberDiff line numberDiff line change
@@ -1437,3 +1437,50 @@ def test_merge_asof_index_behavior(kwargs):
14371437
index=index,
14381438
)
14391439
tm.assert_frame_equal(result, expected)
1440+
1441+
1442+
def test_merge_asof_numeri_column_in_index():
1443+
# GH#34488
1444+
left = pd.DataFrame({"b": [10, 11, 12]}, index=Index([1, 2, 3], name="a"))
1445+
right = pd.DataFrame({"c": [20, 21, 22]}, index=Index([0, 2, 3], name="a"))
1446+
1447+
result = merge_asof(left, right, left_on="a", right_on="a")
1448+
expected = pd.DataFrame({"a": [1, 2, 3], "b": [10, 11, 12], "c": [20, 21, 22]})
1449+
tm.assert_frame_equal(result, expected)
1450+
1451+
1452+
def test_merge_asof_numeri_column_in_multiindex():
1453+
# GH#34488
1454+
left = pd.DataFrame(
1455+
{"b": [10, 11, 12]},
1456+
index=pd.MultiIndex.from_arrays([[1, 2, 3], ["a", "b", "c"]], names=["a", "z"]),
1457+
)
1458+
right = pd.DataFrame(
1459+
{"c": [20, 21, 22]},
1460+
index=pd.MultiIndex.from_arrays([[1, 2, 3], ["x", "y", "z"]], names=["a", "y"]),
1461+
)
1462+
1463+
result = merge_asof(left, right, left_on="a", right_on="a")
1464+
expected = pd.DataFrame({"a": [1, 2, 3], "b": [10, 11, 12], "c": [20, 21, 22]})
1465+
tm.assert_frame_equal(result, expected)
1466+
1467+
1468+
def test_merge_asof_numeri_column_in_index_object_dtype():
1469+
# GH#34488
1470+
left = pd.DataFrame({"b": [10, 11, 12]}, index=Index(["1", "2", "3"], name="a"))
1471+
right = pd.DataFrame({"c": [20, 21, 22]}, index=Index(["m", "n", "o"], name="a"))
1472+
1473+
with pytest.raises(
1474+
MergeError,
1475+
match=r"Incompatible merge dtype, .*, both sides must have numeric dtype",
1476+
):
1477+
merge_asof(left, right, left_on="a", right_on="a")
1478+
1479+
left = left.reset_index().set_index(["a", "b"])
1480+
right = right.reset_index().set_index(["a", "c"])
1481+
1482+
with pytest.raises(
1483+
MergeError,
1484+
match=r"Incompatible merge dtype, .*, both sides must have numeric dtype",
1485+
):
1486+
merge_asof(left, right, left_on="a", right_on="a")

0 commit comments

Comments
 (0)