【问题标题】:Pandas: impose datetime timeline from one dataframe into another dataframe熊猫:将日期时间时间线从一个数据帧强加到另一个数据帧
【发布时间】:2019-04-06 05:54:53
【问题描述】:

我有这两个数据框:

main_df:

    value    feed_id                created_at  
0     0.0  1010077.0 2019-03-06 07:38:18-05:00   
1     1.0  1010077.0 2019-03-06 07:39:26-05:00   
2     1.0  1010077.0 2019-03-06 07:40:33-05:00   
3     1.0  1010077.0 2019-03-06 07:41:41-05:00   
4     1.0  1010077.0 2019-03-06 07:42:49-05:00   
5     1.0  1010077.0 2019-03-06 07:43:56-05:00   

aux_df:

       value    feed_id                created_at
0  20.298492  1009408.0 2019-03-06 07:35:33-05:00
1  20.315002  1009408.0 2019-03-06 07:36:34-05:00
2  20.315002  1009408.0 2019-03-06 07:37:36-05:00
3  20.359650  1009408.0 2019-03-06 07:38:36-05:00
4  20.359650  1009408.0 2019-03-06 07:39:37-05:00
5  20.383179  1009408.0 2019-03-06 07:40:38-05:00
6  20.383179  1009408.0 2019-03-06 07:41:38-05:00
7  20.449524  1009408.0 2019-03-06 07:42:39-05:00
8  20.449524  1009408.0 2019-03-06 07:43:40-05:00
9  20.521912  1009408.0 2019-03-06 07:44:41-05:00

在这种情况下,我想要以下 (final_df):我想要将 aux_df 的“created_at”列中描述的“时间线”完全合并到 main_df,无论它在两列中是否有共同值。对于常见的,我采用整个时间戳并忽略以秒为单位的部分(注意所有值如何按相同的日期、小时和分钟对齐,而不是秒)。

       value    feed_id                created_at
0        nan        nan 2019-03-06 07:35:33-05:00
1        nan        nan 2019-03-06 07:36:34-05:00
2        nan        nan 2019-03-06 07:37:36-05:00
3        0.0  1010077.0 2019-03-06 07:38:36-05:00
4        1.0  1010077.0 2019-03-06 07:39:37-05:00
5        1.0  1010077.0 2019-03-06 07:40:38-05:00
6        1.0  1010077.0 2019-03-06 07:41:38-05:00
7        1.0  1010077.0 2019-03-06 07:42:39-05:00
8        1.0  1010077.0 2019-03-06 07:43:40-05:00
9        nan        nan 2019-03-06 07:44:41-05:00

我尝试过但没有成功的策略:

  1. 在两个名为“created_at_2”的数据框上使用 在每个时间戳上按分钟“四舍五入”,所以我可以丢弃 在我进行合并之前,时间戳的秒部分。
  2. 使用合并。

    main_df['created_at_2'] = main_df.created_at.dt.round('min') aux_df['created_at_2'] = aux_df.created_at.dt.round('min') final_df = pd.merge(main_df, aux_df, on=['created_at_2'], how='inner')

但如本例所示,此方法并不可靠。当您对 2019-03-06 07:40:33-05:00 这样的时间戳进行四舍五入时,您将得到 41 分钟而不是 40 分钟。我需要一个连续的按分钟列。

我可以使用这个重新格式化时间戳时间线:

main_df.created_at.map(lambda t: t.strftime('%Y-%m-%d %H:%M'))
aux_df.created_at.map(lambda t: t.strftime('%Y-%m-%d %H:%M'))
final_df = pd.merge(main_df, aux_df, on=['created_at_2'], how='inner')

但不确定此方法是否可靠,我仍然需要索引“created_at”列中不常见的值。那么,有没有更合适的方法来实现呢?

提前致谢!

【问题讨论】:

    标签: python pandas dataframe merge


    【解决方案1】:

    一个想法是使用merge_asof,但最后一行不同:

    main_df['created_at'] = pd.to_datetime(main_df['created_at'])
    aux_df['created_at'] = pd.to_datetime(aux_df['created_at'])
    
    df = pd.merge_asof(aux_df[['created_at']], main_df, on=['created_at'])
    print (df)
                     created_at  value    feed_id
    0 2019-03-06 07:35:33-05:00    NaN        NaN
    1 2019-03-06 07:36:34-05:00    NaN        NaN
    2 2019-03-06 07:37:36-05:00    NaN        NaN
    3 2019-03-06 07:38:36-05:00    0.0  1010077.0
    4 2019-03-06 07:39:37-05:00    1.0  1010077.0
    5 2019-03-06 07:40:38-05:00    1.0  1010077.0
    6 2019-03-06 07:41:38-05:00    1.0  1010077.0
    7 2019-03-06 07:42:39-05:00    1.0  1010077.0
    8 2019-03-06 07:43:40-05:00    1.0  1010077.0
    9 2019-03-06 07:44:41-05:00    1.0  1010077.0
    

    另一种是使用Series.dt.floor 而不是round

    main_df['created_at'] = pd.to_datetime(main_df['created_at'])
    aux_df['created_at'] = pd.to_datetime(aux_df['created_at'])
    main_df['created_at_2'] = main_df.created_at.dt.floor('min') 
    aux_df['created_at_2'] = aux_df.created_at.dt.floor('min') 
    
    df = pd.merge(aux_df[['created_at_2']], main_df, on=['created_at_2'], how='left')
    print (df)
                   created_at_2  value    feed_id                created_at
    0 2019-03-06 07:35:00-05:00    NaN        NaN                       NaT
    1 2019-03-06 07:36:00-05:00    NaN        NaN                       NaT
    2 2019-03-06 07:37:00-05:00    NaN        NaN                       NaT
    3 2019-03-06 07:38:00-05:00    0.0  1010077.0 2019-03-06 07:38:18-05:00
    4 2019-03-06 07:39:00-05:00    1.0  1010077.0 2019-03-06 07:39:26-05:00
    5 2019-03-06 07:40:00-05:00    1.0  1010077.0 2019-03-06 07:40:33-05:00
    6 2019-03-06 07:41:00-05:00    1.0  1010077.0 2019-03-06 07:41:41-05:00
    7 2019-03-06 07:42:00-05:00    1.0  1010077.0 2019-03-06 07:42:49-05:00
    8 2019-03-06 07:43:00-05:00    1.0  1010077.0 2019-03-06 07:43:56-05:00
    9 2019-03-06 07:44:00-05:00    NaN        NaN                       NaT
    

    【讨论】:

    • 我想出了另一个解决方案,由于我没有启用该选项,因此我无法正确发布该解决方案。但你的也很有效,最后我还是和我在一起。让我描述一下我在这里所做的事情: main_df 的重新格式化时间戳被用作索引,然后我使用 .loc 索引这些值: aux_df.created_at_2.values.tolist() ,然后我应用了合并。感谢您提供其他方法! :)
    猜你喜欢
    • 2016-07-17
    • 2018-08-18
    • 2019-07-02
    • 1970-01-01
    • 2022-01-24
    • 1970-01-01
    • 2021-12-02
    • 2021-03-02
    • 2019-10-31
    相关资源
    最近更新 更多