Skip to content

BUG: merge_asof not handling allow_exact_matches and tolerance on first entry #13698

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

Closed
wants to merge 1 commit into from
Closed
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: 1 addition & 1 deletion doc/source/whatsnew/v0.19.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ The following are now part of this API:
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

A long-time requested feature has been added through the :func:`merge_asof` function, to
support asof style joining of time-series. (:issue:`1870`). Full documentation is
support asof style joining of time-series. (:issue:`1870`, :issue:`13695`). Full documentation is
:ref:`here <merging.merge_asof>`

The :func:`merge_asof` performs an asof merge, which is similar to a left-join
Expand Down
18 changes: 10 additions & 8 deletions pandas/src/join.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -193,11 +193,12 @@ def left_outer_asof_join(ndarray[int64_t] left, ndarray[int64_t] right,
diff = left_val - right_val

# do we allow exact matches
if allow_exact_matches and diff > tol:
right_indexer[indexer] = -1
continue
if allow_exact_matches:
if diff > tol:
right_indexer[indexer] = -1
continue
elif not allow_exact_matches:
if diff >= tol:
if diff >= tol or lc == rc:
right_indexer[indexer] = -1
continue

Expand All @@ -220,13 +221,14 @@ def left_outer_asof_join(ndarray[int64_t] left, ndarray[int64_t] right,
diff = left_val - right_val

# do we allow exact matches
if allow_exact_matches and diff > tol:
right_indexer[indexer] = -1
continue
if allow_exact_matches:
if diff > tol:
right_indexer[indexer] = -1
continue

# we don't allow exact matches
elif not allow_exact_matches:
if diff >= tol or not right_pos:
if diff >= tol or lc == rc:
right_indexer[indexer] = -1
else:
right_indexer[indexer] = right_pos - 1
Expand Down
33 changes: 33 additions & 0 deletions pandas/tools/tests/test_merge_asof.py
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,39 @@ def test_allow_exact_matches_and_tolerance(self):
expected = self.allow_exact_matches_and_tolerance
assert_frame_equal(result, expected)

def test_allow_exact_matches_and_tolerance2(self):
# GH 13695
df1 = pd.DataFrame({
'time': pd.to_datetime(['2016-07-15 13:30:00.030']),
'username': ['bob']})
df2 = pd.DataFrame({
'time': pd.to_datetime(['2016-07-15 13:30:00.000',
'2016-07-15 13:30:00.030']),
'version': [1, 2]})

result = pd.merge_asof(df1, df2, on='time')
expected = pd.DataFrame({
'time': pd.to_datetime(['2016-07-15 13:30:00.030']),
'username': ['bob'],
'version': [2]})
assert_frame_equal(result, expected)

result = pd.merge_asof(df1, df2, on='time', allow_exact_matches=False)
expected = pd.DataFrame({
'time': pd.to_datetime(['2016-07-15 13:30:00.030']),
'username': ['bob'],
'version': [1]})
assert_frame_equal(result, expected)

result = pd.merge_asof(df1, df2, on='time', allow_exact_matches=False,
tolerance=pd.Timedelta('10ms'))
expected = pd.DataFrame({
'time': pd.to_datetime(['2016-07-15 13:30:00.030']),
'username': ['bob'],
'version': [np.nan]})
assert_frame_equal(result, expected)


if __name__ == '__main__':
nose.runmodule(argv=[__file__, '-vvs', '-x', '--pdb', '--pdb-failure'],
exit=False)