code: def merge_asof(
      left,
      right,
      on=None,
      left_on=None,
      right_on=None,
      left_index=False,
      right_index=False,
      by=None,
      left_by=None,
      right_by=None,
      suffixes=("_x", "_y"),
      tolerance=None,
      allow_exact_matches=True,
      direction="backward",
  ):
      """Perform an asof merge. This is similar to a left-join except that we
      match on nearest key rather than equal keys.
  
      Both DataFrames must be sorted by the key.
  
      For each row in the left DataFrame:
  
        - A "backward" search selects the last row in the right DataFrame whose
          'on' key is less than or equal to the left's key.
  
        - A "forward" search selects the first row in the right DataFrame whose
          'on' key is greater than or equal to the left's key.
  
        - A "nearest" search selects the row in the right DataFrame whose 'on'
          key is closest in absolute distance to the left's key.
  
      The default is "backward" and is compatible in versions below 0.20.0.
      The direction parameter was added in version 0.20.0 and introduces
      "forward" and "nearest".
  
      Optionally match on equivalent keys with 'by' before searching with 'on'.
  
      .. versionadded:: 0.19.0
  
      Parameters
      ----------
      left : DataFrame
      right : DataFrame
      on : label
          Field name to join on. Must be found in both DataFrames.
          The data MUST be ordered. Furthermore this must be a numeric column,
          such as datetimelike, integer, or float. On or left_on/right_on
          must be given.
      left_on : label
          Field name to join on in left DataFrame.
      right_on : label
          Field name to join on in right DataFrame.
      left_index : boolean
          Use the index of the left DataFrame as the join key.
  
          .. versionadded:: 0.19.2
  
      right_index : boolean
          Use the index of the right DataFrame as the join key.
  
          .. versionadded:: 0.19.2
  
      by : column name or list of column names
          Match on these columns before performing merge operation.
      left_by : column name
          Field names to match on in the left DataFrame.
  
          .. versionadded:: 0.19.2
  
      right_by : column name
          Field names to match on in the right DataFrame.
  
          .. versionadded:: 0.19.2
  
      suffixes : 2-length sequence (tuple, list, ...)
          Suffix to apply to overlapping column names in the left and right
          side, respectively.
      tolerance : integer or Timedelta, optional, default None
          Select asof tolerance within this range; must be compatible
          with the merge index.
      allow_exact_matches : boolean, default True
  
          - If True, allow matching with the same 'on' value
            (i.e. less-than-or-equal-to / greater-than-or-equal-to)
          - If False, don't match the same 'on' value
            (i.e., strictly less-than / strictly greater-than)
  
      direction : 'backward' (default), 'forward', or 'nearest'
          Whether to search for prior, subsequent, or closest matches.
  
          .. versionadded:: 0.20.0
  
      Returns
      -------
      merged : DataFrame
  
      See Also
      --------
      merge
      merge_ordered
  
      Examples
      --------
      >>> left = pd.DataFrame({'a': [1, 5, 10], 'left_val': ['a', 'b', 'c']})
      >>> left
          a left_val
      0   1        a
      1   5        b
      2  10        c
  
      >>> right = pd.DataFrame({'a': [1, 2, 3, 6, 7],
      ...                       'right_val': [1, 2, 3, 6, 7]})
      >>> right
         a  right_val
      0  1          1
      1  2          2
      2  3          3
      3  6          6
      4  7          7
  
      >>> pd.merge_asof(left, right, on='a')
          a left_val  right_val
      0   1        a          1
      1   5        b          3
      2  10        c          7
  
      >>> pd.merge_asof(left, right, on='a', allow_exact_matches=False)
          a left_val  right_val
      0   1        a        NaN
      1   5        b        3.0
      2  10        c        7.0
  
      >>> pd.merge_asof(left, right, on='a', direction='forward')
          a left_val  right_val
      0   1        a        1.0
      1   5        b        6.0
      2  10        c        NaN
  
      >>> pd.merge_asof(left, right, on='a', direction='nearest')
          a left_val  right_val
      0   1        a          1
      1   5        b          6
      2  10        c          7
  
      We can use indexed DataFrames as well.
  
      >>> left = pd.DataFrame({'left_val': ['a', 'b', 'c']}, index=[1, 5, 10])
      >>> left
         left_val
      1         a
      5         b
      10        c
  
      >>> right = pd.DataFrame({'right_val': [1, 2, 3, 6, 7]},
      ...                      index=[1, 2, 3, 6, 7])
      >>> right
         right_val
      1          1
      2          2
      3          3
      6          6
      7          7
  
      >>> pd.merge_asof(left, right, left_index=True, right_index=True)
         left_val  right_val
      1         a          1
      5         b          3
      10        c          7
  
      Here is a real-world times-series example
  
      >>> quotes
                           time ticker     bid     ask
      0 2016-05-25 13:30:00.023   GOOG  720.50  720.93
      1 2016-05-25 13:30:00.023   MSFT   51.95   51.96
      2 2016-05-25 13:30:00.030   MSFT   51.97   51.98
      3 2016-05-25 13:30:00.041   MSFT   51.99   52.00
      4 2016-05-25 13:30:00.048   GOOG  720.50  720.93
      5 2016-05-25 13:30:00.049   AAPL   97.99   98.01
      6 2016-05-25 13:30:00.072   GOOG  720.50  720.88
      7 2016-05-25 13:30:00.075   MSFT   52.01   52.03
  
      >>> trades
                           time ticker   price  quantity
      0 2016-05-25 13:30:00.023   MSFT   51.95        75
      1 2016-05-25 13:30:00.038   MSFT   51.95       155
      2 2016-05-25 13:30:00.048   GOOG  720.77       100
      3 2016-05-25 13:30:00.048   GOOG  720.92       100
      4 2016-05-25 13:30:00.048   AAPL   98.00       100
  
      By default we are taking the asof of the quotes
  
      >>> pd.merge_asof(trades, quotes,
      ...                       on='time',
      ...                       by='ticker')
                           time ticker   price  quantity     bid     ask
      0 2016-05-25 13:30:00.023   MSFT   51.95        75   51.95   51.96
      1 2016-05-25 13:30:00.038   MSFT   51.95       155   51.97   51.98
      2 2016-05-25 13:30:00.048   GOOG  720.77       100  720.50  720.93
      3 2016-05-25 13:30:00.048   GOOG  720.92       100  720.50  720.93
      4 2016-05-25 13:30:00.048   AAPL   98.00       100     NaN     NaN
  
      We only asof within 2ms between the quote time and the trade time
  
      >>> pd.merge_asof(trades, quotes,
      ...                       on='time',
      ...                       by='ticker',
      ...                       tolerance=pd.Timedelta('2ms'))
                           time ticker   price  quantity     bid     ask
      0 2016-05-25 13:30:00.023   MSFT   51.95        75   51.95   51.96
      1 2016-05-25 13:30:00.038   MSFT   51.95       155     NaN     NaN
      2 2016-05-25 13:30:00.048   GOOG  720.77       100  720.50  720.93
      3 2016-05-25 13:30:00.048   GOOG  720.92       100  720.50  720.93
      4 2016-05-25 13:30:00.048   AAPL   98.00       100     NaN     NaN
  
      We only asof within 10ms between the quote time and the trade time
      and we exclude exact matches on time. However *prior* data will
      propagate forward
  
      >>> pd.merge_asof(trades, quotes,
      ...                       on='time',
      ...                       by='ticker',
      ...                       tolerance=pd.Timedelta('10ms'),
      ...                       allow_exact_matches=False)
                           time ticker   price  quantity     bid     ask
      0 2016-05-25 13:30:00.023   MSFT   51.95        75     NaN     NaN
      1 2016-05-25 13:30:00.038   MSFT   51.95       155   51.97   51.98
      2 2016-05-25 13:30:00.048   GOOG  720.77       100     NaN     NaN
      3 2016-05-25 13:30:00.048   GOOG  720.92       100     NaN     NaN
      4 2016-05-25 13:30:00.048   AAPL   98.00       100     NaN     NaN
      """
      op = _AsOfMerge(
          left,
          right,
          on=on,
          left_on=left_on,
          right_on=right_on,
          left_index=left_index,
          right_index=right_index,
          by=by,
          left_by=left_by,
          right_by=right_by,
          suffixes=suffixes,
          how="asof",
          tolerance=tolerance,
          allow_exact_matches=allow_exact_matches,
          direction=direction,
      )
      return op.get_result()
  
imports: import copy
  import string
  import warnings
  import numpy
  from pandas._libs import hashtable, join, lib
  import pandas.compat
  from pandas.compat import filter, lzip, map, range, zip
  from pandas.errors import MergeError
  from pandas.util._decorators import Appender, Substitution
  from pandas.core.dtypes.common import ensure_float64, ensure_int64, ensure_object, is_array_like, is_bool, is_bool_dtype, is_categorical_dtype, is_datetime64_dtype, is_datetime64tz_dtype, is_datetimelike, is_dtype_equal, is_extension_array_dtype, is_float_dtype, is_int64_dtype, is_integer, is_integer_dtype, is_list_like, is_number, is_numeric_dtype, is_object_dtype, needs_i8_conversion
  from pandas.core.dtypes.missing import isnull, na_value_for_dtype
  from pandas import Categorical, DataFrame, Index, MultiIndex, Series, Timedelta
  import pandas.core.algorithms
  from pandas.core.arrays.categorical import _recode_for_categories
  import pandas.core.common
  from pandas.core.frame import _merge_doc
  from pandas.core.internals import concatenate_block_managers, items_overlap_with_suffix
  import pandas.core.sorting
  from pandas.core.sorting import is_int64_overflow_possible
label_desc: Use image node_id 4 for calling a global function with example usage: merge_asof(left, right, on, left_on, right_on, left_index, right_index, by, left_by, right_by, suffixes, tolerance, allow_exact_matches, direction) and returns: op