【问题标题】:How to merge two dataframes based on the closest (or most recent) timestamp如何根据最近(或最近)的时间戳合并两个数据帧
【发布时间】:2016-03-23 19:44:29
【问题描述】:

假设我有一个数据框 df1,其中包含“A”和“B”列。 A 是一列时间戳(例如 unixtime),而“B”是一列具有某些值的列。

假设我还有一个包含“C”和“D”列的数据框 df2。 C 也是一个 unixtime 列,而 D 是一个包含一些其他值的列。

我想模糊 mergetimestamp 上的连接的数据帧。但是,如果时间戳不匹配(它们很可能不匹配),我希望它合并到它可以在“C”中找到的“A”中时间戳之前最近的条目。

pd.merge 不支持这一点,我发现自己使用 to_dict() 从数据帧转换,并使用一些迭代来解决这个问题。 pandas 有办法解决这个问题吗?

【问题讨论】:

标签: python pandas


【解决方案1】:

numpy.searchsorted()(see docs) 上找到适合mergeindex 位置 - 希望下面的内容能让您更接近您正在寻找的内容:

start = datetime(2015, 12, 1)
df1 = pd.DataFrame({'A': [start + timedelta(minutes=randrange(60)) for i in range(10)], 'B': [1] * 10}).sort_values('A').reset_index(drop=True)
df2 = pd.DataFrame({'C': [start + timedelta(minutes=randrange(60)) for i in range(10)], 'D': [2] * 10}).sort_values('C').reset_index(drop=True)
df2.index = np.searchsorted(df1.A.values, df2.C.values)
print(pd.merge(left=df1, right=df2, left_index=True, right_index=True, how='left'))

                    A  B                   C   D
0 2015-12-01 00:01:00  1                 NaT NaN
1 2015-12-01 00:02:00  1 2015-12-01 00:02:00   2
2 2015-12-01 00:02:00  1                 NaT NaN
3 2015-12-01 00:12:00  1 2015-12-01 00:05:00   2
4 2015-12-01 00:16:00  1 2015-12-01 00:14:00   2
4 2015-12-01 00:16:00  1 2015-12-01 00:14:00   2
5 2015-12-01 00:28:00  1 2015-12-01 00:22:00   2
6 2015-12-01 00:30:00  1                 NaT NaN
7 2015-12-01 00:39:00  1 2015-12-01 00:31:00   2
7 2015-12-01 00:39:00  1 2015-12-01 00:39:00   2
8 2015-12-01 00:55:00  1 2015-12-01 00:40:00   2
8 2015-12-01 00:55:00  1 2015-12-01 00:46:00   2
8 2015-12-01 00:55:00  1 2015-12-01 00:54:00   2
9 2015-12-01 00:57:00  1                 NaT NaN

【讨论】:

    【解决方案2】:

    基于@Stephan 的回答和@JohnE 的评论,可以使用 pandas.merge_asof for pandas>=0.19.0 完成类似的操作:

    >>> import numpy as np
    >>> import pandas as pd
    >>> from datetime import datetime, timedelta
    >>> a_timestamps = pd.date_range(start, start + timedelta(hours=4.5), freq='30Min')
    >>> c_timestamps = pd.date_range(start, start + timedelta(hours=9), freq='H')
    >>> df1 = pd.DataFrame({'A': a_timestamps, 'B': range(10)})
    
                        A  B
    0 2015-12-01 00:00:00  0
    1 2015-12-01 00:30:00  1
    2 2015-12-01 01:00:00  2
    3 2015-12-01 01:30:00  3
    4 2015-12-01 02:00:00  4
    5 2015-12-01 02:30:00  5
    6 2015-12-01 03:00:00  6
    7 2015-12-01 03:30:00  7
    8 2015-12-01 04:00:00  8
    9 2015-12-01 04:30:00  9
    
    >>> df2 = pd.DataFrame({'C': c_timestamps, 'D': range(10, 20)})
    
                       C   D
    0 2015-12-01 00:00:00  10
    1 2015-12-01 01:00:00  11
    2 2015-12-01 02:00:00  12
    3 2015-12-01 03:00:00  13
    4 2015-12-01 04:00:00  14
    5 2015-12-01 05:00:00  15
    6 2015-12-01 06:00:00  16
    7 2015-12-01 07:00:00  17
    8 2015-12-01 08:00:00  18
    9 2015-12-01 09:00:00  19
    
    >>> pd.merge_asof(left=df1, right=df2, left_on='A', right_on='C')
    
                        A  B                   C   D
    0 2015-12-01 00:00:00  0 2015-12-01 00:00:00  10
    1 2015-12-01 00:30:00  1 2015-12-01 00:00:00  10
    2 2015-12-01 01:00:00  2 2015-12-01 01:00:00  11
    3 2015-12-01 01:30:00  3 2015-12-01 01:00:00  11
    4 2015-12-01 02:00:00  4 2015-12-01 02:00:00  12
    5 2015-12-01 02:30:00  5 2015-12-01 02:00:00  12
    6 2015-12-01 03:00:00  6 2015-12-01 03:00:00  13
    7 2015-12-01 03:30:00  7 2015-12-01 03:00:00  13
    8 2015-12-01 04:00:00  8 2015-12-01 04:00:00  14
    9 2015-12-01 04:30:00  9 2015-12-01 04:00:00  14
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-27
      • 2016-12-12
      • 1970-01-01
      • 2020-09-23
      • 2020-12-15
      • 1970-01-01
      • 2019-05-27
      • 1970-01-01
      相关资源
      最近更新 更多