pandas.merge_asof¶
-
pandas.
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)[source]¶ 执行asof合并。这类似于左连接,除了我们匹配最近的键而不是相等的键。
对于左侧DataFrame中的每一行,我们选择右边DataFrame中的最后一行,其'on'键小于或等于左侧的键。两个DataFrames都必须按键排序。
可选择使用'by'匹配等效键,然后再使用'on'搜索最接近的匹配。
版本0.19.0中的新功能。
参数: 左 T0>:DataFrame
右:DataFrame
on:label
要加入的字段名称。必须在两个DataFrames中都找到。数据必须排序。此外,它必须是数字列,例如datetimelike,integer或float。必须给出on或left_on / right_on。
left_on:label
要在左侧DataFrame中加入的字段名称。
right_on:label
要在右边DataFrame中加入的字段名称。
left_index:boolean
使用左侧DataFrame的索引作为连接键。
版本0.19.2中的新功能。
right_index:boolean
使用正确的DataFrame的索引作为连接键。
版本0.19.2中的新功能。
由:列名称或列名称列表
在执行合并操作之前匹配这些列。
left_by:列名称
要在左侧DataFrame中匹配的字段名称。
版本0.19.2中的新功能。
right_by:列名称
要在右侧DataFrame中匹配的字段名称。
版本0.19.2中的新功能。
后缀:2长度序列(tuple,list,...)
后缀,分别应用于左侧和右侧的重叠列名称
公差:整数或Timedelta,可选,默认无
在此范围内选择asof tolerance;必须与合并索引兼容。
allow_exact_matches:boolean,default True
- 如果为True,则允许匹配相同的“on”值(即小于或等于)
- 如果为False,则不匹配相同的'on'值(即严格小于)
返回: 合并:DataFrame
也可以看看
例子
>>> left a left_val 0 1 a 1 5 b 2 10 c
>>> 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_ordered()
实现类似的结果,虽然它不是那么高性能。>>> (pd.merge_ordered(left, right, on='a') ... .ffill() ... .drop_duplicates(['left_val']) ... ) a left_val right_val 0 1 a 1.0 3 5 b 3.0 6 10 c 7.0
我们也可以使用索引的DataFrames。
>>> left left_val 1 a 5 b 10 c
>>> 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 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
默认情况下,我们使用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 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