代码之家  ›  专栏  ›  技术社区  ›  00__00__00

将数据帧与时间戳和间隔合并

  •  1
  • 00__00__00  · 技术社区  · 7 年前

    我有两个数据帧。

    DF1包含数字和时间戳。这是一套很大的。

    df1.head()
    Out[292]: 
    2016-08-31 08:09:00     1.0
    2016-08-31 08:11:00     7.0
    2016-08-31 08:14:00    90.0
    

    DF2包含间隔

    d2.head()
    Out[292]:        
       start                 stop                         C
    2016-08-31 08:09:00     2016-08-31 08:12:00         'a'
    2016-08-31 08:13:00     2016-08-31 08:20:00         'b'
    2016-08-31 08:20:00     2016-08-31 08:45:00         'c'
    

    我想添加一个新列 C 到 df1 这样的价值 C 与中的值相对应 df2 对于包含索引的间隔 DF1 .

    预期结果

     df1.head()
        Out[292]:                      C
        2016-08-31 08:09:00     1.0   'a'
        2016-08-31 08:11:00     7.0   'a'
        2016-08-31 08:14:00    90.0   'b'
    

    到目前为止,我已经尝试过:

     df1.loc[:,'C']=df1.index.map(lambda i:df2[np.logical_and(i>df2.starti<df2.stop)].C)
    

    但是,它非常低效,并且在某些情况下会崩溃,因为在DF2的间隔列表中缺少索引值。

    如何有效地做到这一点?

    1 回复  |  直到 7 年前
        1
  •  3
  •   jezrael    7 年前

    创造 IntervalIndex 通过 IntervalIndex.from_arrays 第一:

    s = pd.IntervalIndex.from_arrays(df2['start'], df2['stop'], 'both')
    print (s)
    IntervalIndex([[2016-08-31 08:09:00, 2016-08-31 08:12:00], 
                   [2016-08-31 08:13:00, 2016-08-31 08:20:00],
                   [2016-08-31 08:20:00, 2016-08-31 08:45:00]],
                  closed='both',
                  dtype='interval[datetime64[ns]]')
    

    然后 set_index 由新 中间指数 按创建的数组设置为新列 values :

    df1['C'] = df2.set_index(s).loc[df1.index, 'C'].values
    print (df1)
                            A  C
    2016-08-31 08:09:00   1.0  a
    2016-08-31 08:11:00   7.0  a
    2016-08-31 08:14:00  90.0  b
    

    编辑:

    s = pd.IntervalIndex.from_arrays(df2['start'].astype(np.int64), 
                                     df2['stop'].astype(np.int64), 'both')
    print (s)
    IntervalIndex([[1472630940000000000, 1472631120000000000], 
                   [1472631180000000000, 1472631600000000000], 
                   [1472631600000000000, 1472633100000000000]],
                  closed='both',
                  dtype='interval[int64]')
    
    df1['C'] = df2.set_index(s).loc[df1.index.astype(np.int64), 'C'].values
    print (df1)
                            A  C
    2016-08-31 08:09:00   1.0  a
    2016-08-31 08:11:00   7.0  a
    2016-08-31 08:14:00  90.0  b