【问题标题】:How to merge a row to its closest row (based on timestamp) in Pandas?如何在 Pandas 中将一行合并到最近的行(基于时间戳)?
【发布时间】:2020-07-30 06:14:18
【问题描述】:

我对 Pandas 比较陌生,所以如果我的问题没有正确表达,我深表歉意,我在这里有一个数据集,

                       t  HVAC1_S1  HVAC2_S1  ...  HVAC4_S1  HVAC5_S1  HVAC6_S1
0       2009-08-18 18:12     711.0       0.0  ...       0.0       0.0       0.0
1       2009-08-18 18:14     705.0     734.0  ...       0.0     725.0     711.0
2       2009-08-18 18:15       0.0       0.0  ...     730.0       0.0       0.0
3       2009-08-18 18:29       0.0     721.0  ...     716.0     718.0     712.0
4       2009-08-18 18:30     705.0       0.0  ...       0.0       0.0       0.0
                 ...       ...       ...  ...       ...       ...       ...
156033  2012-11-09 21:59     714.0     720.0  ...     739.0       0.0     727.0
156034  2012-11-09 22:00       0.0       0.0  ...       0.0     743.0       0.0
156035  2012-11-09 22:14     723.0     729.0  ...     734.0     743.0     732.0
156036  2012-11-09 22:29     718.0     732.0  ...       0.0     739.0     725.0
156037  2012-11-09 22:30       0.0       0.0  ...     739.0       0.0       0.0

因此,如果您注意到时间戳,例如索引“1”,即在 2009 年 8 月 18 日 18 点 14 分,有 5 个读数被读取(其中一个不可见,因为...)。现在实际上总共有 6 个读数,但最后一个读数是在下一分钟,即 2009-08-18 18:15 进行的。好吧,这有点令人困惑,因为这里没有秒数。此外,一次读取所有 6 个读数,然后在 15 分钟后再次测量。现在,在测量一个值时,通常会在下一分钟测量,因此它位于一个新行中。

我想设置 1 分钟的容差并将这些行的值(如索引 2,4、156034、156037)合并到之前的行并从数据框中删除该行

所以例如我想获得我的数据框,

                       t  HVAC1_S1  HVAC2_S1  ...  HVAC4_S1  HVAC5_S1  HVAC6_S1
0       2009-08-18 18:12     711.0       0.0  ...       0.0       0.0       0.0
1       2009-08-18 18:14     705.0     734.0  ...      730.0     725.0     711.0
2       2009-08-18 18:29     705.0     721.0  ...     716.0     718.0     712.0
                 ...       ...       ...  ...       ...       ...       ...
156033  2012-11-09 21:59     714.0     720.0  ...     739.0     743.0     727.0
156035  2012-11-09 22:14     723.0     729.0  ...     734.0     743.0     732.0
156036  2012-11-09 22:29     718.0     732.0  ...     739.0     739.0     725.0

注意:索引 0 可以忽略,因为它超出了 1 分钟的容差。

请提供您宝贵的建议。谢谢!

【问题讨论】:

    标签: python python-3.x pandas timestamp time-series


    【解决方案1】:

    您可以使用 asof 合并将 DataFrame 与其自身合并。选择正向,并且不允许完全匹配(否则同一行将始终与自身合并)。我们可以指定 1 分钟的容差。我们需要在合并中带上索引,以便我们可以在合并后删除与其他行合并的行。

    合并后,我们将拥有 _x_y 列,我们可以删除它们并沿列轴分组以组合它们。

    输入数据:

                        t  HVAC1_S1  HVAC2_S1  HVAC4_S1  HVAC5_S1  HVAC6_S1
    0 2009-08-18 18:12:00     711.0       0.0       0.0       0.0       0.0
    1 2009-08-18 18:14:00     705.0     734.0       0.0     725.0     711.0
    2 2009-08-18 18:15:00       0.0       0.0     730.0       0.0       0.0
    3 2009-08-18 18:29:00       0.0     721.0     716.0     718.0     712.0
    4 2009-08-18 18:30:00     705.0       0.0       0.0       0.0       0.0
    

    代码:

    import pandas as pd
    #df['t'] = pd.to_datetime(df['t'])  #If not datetime
    
    res = pd.merge_asof(df.reset_index(), df.reset_index(), 
                        on='t', 
                        direction='forward', 
                        allow_exact_matches=False,
                        tolerance=pd.Timedelta('1min'))
    res = res.set_index('t')
    
    res = res[~res.index_x.isin(res.index_y)]  #Remove rows that merged with others
    res = res.drop(columns=['index_x', 'index_y'])
    
    res = res.groupby(res.columns.str.rsplit('_', n=1).str[0], axis=1).sum()
    

    输出:

                         HVAC1_S1  HVAC2_S1  HVAC4_S1  HVAC5_S1  HVAC6_S1
    t                                                                    
    2009-08-18 18:12:00     711.0       0.0       0.0       0.0       0.0
    2009-08-18 18:14:00     705.0     734.0     730.0     725.0     711.0
    2009-08-18 18:29:00     705.0     721.0     716.0     718.0     712.0
    

    【讨论】:

    • 您好,谢谢您的回答,但我收到一个错误 "MergeError: key must be integer, timestamp or float" 。你能解释一下我哪里错了吗?
    • @MurtazaBasu 哦,你必须有字符串键。在执行此操作之前,请尝试 df['t'] = pd.to_datetime(df['t']),以便 pandas 将它们识别为日期。
    猜你喜欢
    • 2021-06-13
    • 2022-08-16
    • 2020-01-29
    • 2015-03-14
    • 2016-04-25
    • 1970-01-01
    • 1970-01-01
    • 2021-10-04
    相关资源
    最近更新 更多