使用merge_asof()而不进行替换

时间:2019-12-19 15:58:30

标签: python pandas

我有以下两个DataFrame(分别为df1和df2):

df1 = 

                      Type       Price  Size
Dates                                       
2019-08-16 00:00:34  TRADE  130.859375     1
2019-08-16 00:00:57  TRADE  130.859375     5
2019-08-16 00:00:57  TRADE  130.859375     2
2019-08-16 00:01:00  TRADE  130.859375     8

df2 = 

                              Trade Price Trade Volume
Time                                                  
2019-08-16 00:00:34.875364542     130.859            1
2019-08-16 00:00:57.720986127     130.859            5
2019-08-16 00:00:57.731894016     130.859            2
2019-08-16 00:01:00.093161344     130.859            8

df1的时间不如df2的时间精确,这意味着我不能仅对索引进行合并。此外,不能保证它们的长度相同(我不能仅将它们连接起来)。

我一直在尝试使用merge_asof在最近的时间进行合并:

mergedData = pd.merge_asof(df1.reset_index(), df2.reset_index(), left_on=['Dates'], right_on=['Time'], direction='nearest')

似乎一旦进行了匹配,它仍然可以作为潜在的匹配,因此2019-08-16 00:00:57之类的时间将与2019-08-16 00:00:57.720986127进行两次匹配。有什么可能的解决方案吗?

2 个答案:

答案 0 :(得分:0)

合并前尽量适应时间格式

df1['time'] = pd.to_datetime(df1['time'], format= '%d-%m-%Y %H:%M:%S.%f')
df2['time'] = pd.to_datetime(df2['time'], format= '%d-%m-%Y %H:%M:%S.%f')

答案 1 :(得分:0)

这很棘手,因为您尚未指定有关如何及时合并彼此靠近的多行的逻辑。此外,merge_asof() 只能进行左合并,因此您甚至无法进行完整的外连接,然后在结果中对重复项进行排序。

从您给出的示例中,一个弱假设是您可能可以依靠音量来消除 df1 中的多个同一秒行的歧义。

如果该假设适用于您的整个数据,那么您可以请求完全匹配的数量:

df3 = pd.merge_asof(
    df2.reset_index(),
    df1.reset_index(),
    left_by='Trade Volume', right_by='Size',
    left_on=['Time'], right_on=['Dates'], direction='nearest')

# df3:
                           Time  Trade Price  Trade Volume  Size  \
0 2019-08-16 00:00:34.875364542      130.859             1     1   
1 2019-08-16 00:00:57.720986127      130.859             5     5   
2 2019-08-16 00:00:57.731894016      130.859             2     2   
3 2019-08-16 00:01:00.093161344      130.859             8     8   

                Dates   Type       Price  
0 2019-08-16 00:00:34  TRADE  130.859375  
1 2019-08-16 00:00:57  TRADE  130.859375  
2 2019-08-16 00:00:57  TRADE  130.859375  
3 2019-08-16 00:01:00  TRADE  130.859375  

您还可以减少冗余信息(我认为您保留这些信息是为了调试目的):

df3 = pd.merge_asof(df2.rename(columns={'Trade Volume': 'Size'}), df1,
    by='Size', left_index=True, right_index=True, direction='nearest')

# df3:
                               Trade Price  Size   Type       Price
Time                                                               
2019-08-16 00:00:34.875364542      130.859     1  TRADE  130.859375
2019-08-16 00:00:57.720986127      130.859     5  TRADE  130.859375
2019-08-16 00:00:57.731894016      130.859     2  TRADE  130.859375
2019-08-16 00:01:00.093161344      130.859     8  TRADE  130.859375

但最大的警告是上面的假设。如果不成立,请扩展您的示例,并提供预期的输出和逻辑。