Skip to content

Commit b054536

Browse files
committed
BUG: merge_asof not handling allow_exact_matches and tolerance on first entry
closes #13695 Author: Jeff Reback <[email protected]> Closes #13698 from jreback/merge_asof and squashes the following commits: c46dcfa [Jeff Reback] BUG: merge_asof not handling allow_exact_matches and tolerance on first entry
1 parent 9f635cd commit b054536

File tree

3 files changed

+44
-9
lines changed

3 files changed

+44
-9
lines changed

doc/source/whatsnew/v0.19.0.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ The following are now part of this API:
4646
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4747

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

5252
The :func:`merge_asof` performs an asof merge, which is similar to a left-join

pandas/src/join.pyx

+10-8
Original file line numberDiff line numberDiff line change
@@ -193,11 +193,12 @@ def left_outer_asof_join(ndarray[int64_t] left, ndarray[int64_t] right,
193193
diff = left_val - right_val
194194

195195
# do we allow exact matches
196-
if allow_exact_matches and diff > tol:
197-
right_indexer[indexer] = -1
198-
continue
196+
if allow_exact_matches:
197+
if diff > tol:
198+
right_indexer[indexer] = -1
199+
continue
199200
elif not allow_exact_matches:
200-
if diff >= tol:
201+
if diff >= tol or lc == rc:
201202
right_indexer[indexer] = -1
202203
continue
203204

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

222223
# do we allow exact matches
223-
if allow_exact_matches and diff > tol:
224-
right_indexer[indexer] = -1
225-
continue
224+
if allow_exact_matches:
225+
if diff > tol:
226+
right_indexer[indexer] = -1
227+
continue
226228

227229
# we don't allow exact matches
228230
elif not allow_exact_matches:
229-
if diff >= tol or not right_pos:
231+
if diff >= tol or lc == rc:
230232
right_indexer[indexer] = -1
231233
else:
232234
right_indexer[indexer] = right_pos - 1

pandas/tools/tests/test_merge_asof.py

+33
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,39 @@ def test_allow_exact_matches_and_tolerance(self):
347347
expected = self.allow_exact_matches_and_tolerance
348348
assert_frame_equal(result, expected)
349349

350+
def test_allow_exact_matches_and_tolerance2(self):
351+
# GH 13695
352+
df1 = pd.DataFrame({
353+
'time': pd.to_datetime(['2016-07-15 13:30:00.030']),
354+
'username': ['bob']})
355+
df2 = pd.DataFrame({
356+
'time': pd.to_datetime(['2016-07-15 13:30:00.000',
357+
'2016-07-15 13:30:00.030']),
358+
'version': [1, 2]})
359+
360+
result = pd.merge_asof(df1, df2, on='time')
361+
expected = pd.DataFrame({
362+
'time': pd.to_datetime(['2016-07-15 13:30:00.030']),
363+
'username': ['bob'],
364+
'version': [2]})
365+
assert_frame_equal(result, expected)
366+
367+
result = pd.merge_asof(df1, df2, on='time', allow_exact_matches=False)
368+
expected = pd.DataFrame({
369+
'time': pd.to_datetime(['2016-07-15 13:30:00.030']),
370+
'username': ['bob'],
371+
'version': [1]})
372+
assert_frame_equal(result, expected)
373+
374+
result = pd.merge_asof(df1, df2, on='time', allow_exact_matches=False,
375+
tolerance=pd.Timedelta('10ms'))
376+
expected = pd.DataFrame({
377+
'time': pd.to_datetime(['2016-07-15 13:30:00.030']),
378+
'username': ['bob'],
379+
'version': [np.nan]})
380+
assert_frame_equal(result, expected)
381+
382+
350383
if __name__ == '__main__':
351384
nose.runmodule(argv=[__file__, '-vvs', '-x', '--pdb', '--pdb-failure'],
352385
exit=False)

0 commit comments

Comments
 (0)