代码之家  ›  专栏  ›  技术社区  ›  Umar.H

用一个条件自求和一个时间序列列

  •  0
  • Umar.H  · 技术社区  · 6 年前

    我目前正在处理从工程工厂收到的一些数据,这些数据大致如下:

        df = pd.DataFrame({'ID' : np.random.randint(1,25,size=5),
    'on/off' : np.random.randint(0,2,size=5),
    'Time' : pd.date_range(start='01/01/2019',periods=5,freq='5s')})
         print(df)
        ID  on/off  Time
    0   17  0   2019-01-01 00:00:00 
    1   21  0   2019-01-01 00:00:05 
    2   12  1   2019-01-01 00:00:10 
    3   12  1   2019-01-01 00:00:15 
    4   12  0   2019-01-01 00:00:20 
    

    开/关栏中的0和1对应于机器打开或关闭的时间(0=打开1=关闭)

    目前,我使用下面这行漂亮的代码来获取数据滚动时我的列之间的差异。

    df['Time Difference'] = (df.time - df.time.shift()) 
    print(df)
        ID  on/off  Time    Time Difference
    0   17  0   2019-01-01 00:00:00 NaT
    1   21  0   2019-01-01 00:00:05 00:00:05
    2   12  1   2019-01-01 00:00:10 00:00:05
    3   12  1   2019-01-01 00:00:15 00:00:05
    4   12  0   2019-01-01 00:00:20 00:00:05
    

    现在,由于这个数据帧相当冗长(每周我将收到大约150K行)

    在下一个0出现之前,计算机器关闭时间(df['on/off]=1)的最佳方法是什么?因此,在上面的例子中,在2019年1月1日,ID 12的机器在00:00:20恢复之前,没有运行15秒。

    我真的很困惑……!我可以按id、s on-off、日期、时间戳对其进行分组,但我不确定如何在单个列中滚动数据位。任何帮助或建议都非常感谢。

    DN

    1 回复  |  直到 6 年前
        1
  •  1
  •   James Dellinger    6 年前

    下面是一个方法,它适用于一台机器的简单示例,该机器在一天的运行过程中在开与关之间变化。不管机器是否在 on off 状态在第一行。

    df = pd.DataFrame({'ID': [12, 12, 12, 12, 12],
                       'on/off': [0,0,1,0,1],
                       'Time': ['2019-01-01 00:00:00', '2019-01-01 00:00:05', '2019-01-01 00:00:10','2019-01-01 00:00:15','2019-01-01 00:00:20']
    })
    
        ID  on/off  Time
    0   12  0       2019-01-01 00:00:00
    1   12  0       2019-01-01 00:00:05
    2   12  1       2019-01-01 00:00:10
    3   12  0       2019-01-01 00:00:15
    4   12  1       2019-01-01 00:00:20
    
    1. 首先我确定 Time 列数据类型为datetime64:

    df['Time'] = pd.to_datetime(df['Time'])

    1. 然后我得到状态改变的所有行的索引(从 远离的 ,或来自 远离的 :
    s = df[df['on/off'].shift(1) != df['on/off']].index
    df = df.loc[s]
    
    1. 然后我创建一个名为 time shift ,显示电源状态更改的最近一行的时间戳:
    df['time shift'] = df['Time'].shift(1)
    

    此时,数据帧如下所示:

        ID  on/off  Time                 time shift
    0   12  0       2019-01-01 00:00:00  NaT
    2   12  1       2019-01-01 00:00:10  2019-01-01 00:00:00
    3   12  0       2019-01-01 00:00:15  2019-01-01 00:00:10
    4   12  1       2019-01-01 00:00:20  2019-01-01 00:00:15
    
    1. 现在,由于我们想计算机器关闭的持续时间,我只查看状态变为 :
    r = df[df['on/off'] == 1].index
    df = df.loc[r]
    

    在这一点上,数据帧看起来和下面一样。注意到 时移 列显示机器最近关闭的点,时间显示在 时间 列,这是机器重新启动时的时间戳。找到这两列之间的差异将为我们提供机器在一天内关闭的每个持续时间的长度:

        ID  on/off  Time                 time shift
    2   12  1       2019-01-01 00:00:10  2019-01-01 00:00:00
    4   12  1       2019-01-01 00:00:20  2019-01-01 00:00:15
    
    1. 下一行通过求和机器所在的每个周期的持续时间来计算总的停机时间。 远离的 状态:
    (df['Time'] - df['time shift']).sum()
    

    输出:

    Timedelta('0 days 00:00:15')
    

    关于熊猫如何 .shift() 方法工作:

    SHIFT获取列中的所有行,并将它们向前或向后移动一定量。 .shift(1) 告诉熊猫将每行的索引向前或向上移动1。 .shift(-1) 告诉熊猫将每行的索引向后或向下移动1。交替放置, 换档(1) 允许您查看前一行索引中列的值,以及 换档(- 1) 允许您在下一行索引处查看列的值,相对于列中的给定行。这是一种比较不同行中列值的简便方法,而不必使用for循环。