pandas.merge_asof # 熊猫。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') ,公差=无, allow_exact_matches = True,方向= '向后')[来源]# 按键距离执行合并。 这与左连接类似,只是我们匹配最近的键而不是相等的键。两个 DataFrame 都必须按键排序。 对于左侧 DataFrame 中的每一行: “向后”搜索选择右侧 DataFrame 中“on”键小于或等于左侧键的最后一行。 “向前”搜索选择右侧 DataFrame 中“on”键大于或等于左侧键的第一行。 “最近”搜索选择右侧 DataFrame 中“on”键在绝对距离上与左侧键最接近的行。 在使用“on”搜索之前,可以选择使用“by”匹配等效键。 参数: 左DataFrame 或命名系列 正确的DataFrame 或命名系列 标签上要加入的字段名称。必须在两个 DataFrame 中找到。数据必须是有序的。此外,这必须是数字列,例如 datetimelike、整数或浮点数。必须给出 On 或 left_on/right_on。 left_on标签要加入左侧 DataFrame 的字段名称。 右侧标签要加入右侧 DataFrame 中的字段名称。 左索引布尔值使用左侧 DataFrame 的索引作为连接键。 右索引布尔值使用右侧 DataFrame 的索引作为连接键。 按列名称或列名称列表在执行合并操作之前匹配这些列。 left_by列名称要在左侧 DataFrame 中匹配的字段名称。 right_by列名称要在右侧 DataFrame 中匹配的字段名称。 后缀2 长度序列(元组、列表……)分别应用于左侧和右侧重叠列名称的后缀。 Tolerance int 或 Timedelta,可选,默认 None在此范围内选择asof公差;必须与合并索引兼容。 allowed_exact_matches bool, 默认 True 如果为 True,则允许匹配相同的“on”值(即小于或等于/大于或等于) 如果为 False,则不匹配相同的“on”值(即严格小于/严格大于)。 方向“向后”(默认)、“向前”或“最近”是否搜索先前、后续或最接近的匹配项。 返回: 数据框 也可以看看 merge与数据库样式的联接合并。 merge_ordered与可选的填充/插值合并。 例子 >>> 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 我们也可以使用索引数据帧。 >>> 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 这是一个现实世界的时间序列示例 >>> quotes = pd.DataFrame( ... { ... "time": [ ... pd.Timestamp("2016-05-25 13:30:00.023"), ... pd.Timestamp("2016-05-25 13:30:00.023"), ... pd.Timestamp("2016-05-25 13:30:00.030"), ... pd.Timestamp("2016-05-25 13:30:00.041"), ... pd.Timestamp("2016-05-25 13:30:00.048"), ... pd.Timestamp("2016-05-25 13:30:00.049"), ... pd.Timestamp("2016-05-25 13:30:00.072"), ... pd.Timestamp("2016-05-25 13:30:00.075") ... ], ... "ticker": [ ... "GOOG", ... "MSFT", ... "MSFT", ... "MSFT", ... "GOOG", ... "AAPL", ... "GOOG", ... "MSFT" ... ], ... "bid": [720.50, 51.95, 51.97, 51.99, 720.50, 97.99, 720.50, 52.01], ... "ask": [720.93, 51.96, 51.98, 52.00, 720.93, 98.01, 720.88, 52.03] ... } ... ) >>> 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 = pd.DataFrame( ... { ... "time": [ ... pd.Timestamp("2016-05-25 13:30:00.023"), ... pd.Timestamp("2016-05-25 13:30:00.038"), ... pd.Timestamp("2016-05-25 13:30:00.048"), ... pd.Timestamp("2016-05-25 13:30:00.048"), ... pd.Timestamp("2016-05-25 13:30:00.048") ... ], ... "ticker": ["MSFT", "MSFT", "GOOG", "GOOG", "AAPL"], ... "price": [51.95, 51.95, 720.77, 720.92, 98.0], ... "quantity": [75, 155, 100, 100, 100] ... } ... ) >>> 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 默认情况下,我们采用报价的 asof >>> 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 我们报价时间和交易时间之间只有2ms之内 >>> 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 我们的报价时间和交易时间之间的误差仅在 10 毫秒之内,并且排除时间上的精确匹配。然而先前的数据将向前传播 >>> 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