【问题标题】:Pandas flatten a time-series dataframe on same activity but different timestampsPandas 将同一活动的时间序列数据帧展平,但时间戳不同
【发布时间】:2021-10-25 17:52:41
【问题描述】:

我希望扁平化某些流程。基本上看的是紧随其后的重复。假设我有一个数据框:

d = {'time': [12-08-2020, 13-08-2020, 14-08-2020, 15-08-2020, 16-08-2020], 'state': [off, on, on, on, off]}
df = pd.DataFrame(data=d)

然后我会使用time.shift() 创建“time_end”列。基本上是下一行的时间。结果:

         time state    time_end
0  12-08-2020   off  13-08-2020
1  13-08-2020    on  14-08-2020
2  14-08-2020    on  15-08-2020
3  15-08-2020    on  16-08-2020
4  16-08-2020   off         NaN

我现在的问题是,如何将其展平,使其实际上变成这样的 3 行:

         time state    time_end
0  12-08-2020   off  13-08-2020
1  13-08-2020    on  16-08-2020
4  16-08-2020   off         NaN

对于我的代码,如果它们后面跟着另一个 on,我不需要重复。任何帮助将不胜感激。

【问题讨论】:

    标签: python pandas time-series


    【解决方案1】:

    我们可以根据当前行的state 值不等于下一行的state 值的位置过滤DataFrame,然后通过将过滤后的time 列移回来创建time_end 列:

    import pandas as pd
    
    df = pd.DataFrame(data={
        'time': ['12-08-2020', '13-08-2020', '14-08-2020', '15-08-2020',
                 '16-08-2020'],
        'state': ['off', 'on', 'on', 'on', 'off']
    })
    
    new_df = df[df['state'].ne(df['state'].shift())].reset_index(drop=True)
    new_df['time_end'] = new_df['time'].shift(-1)
    

    new_df:

             time state    time_end
    0  12-08-2020   off  13-08-2020
    1  13-08-2020    on  16-08-2020
    2  16-08-2020   off         NaN
    

    【讨论】:

      【解决方案2】:

      我们可以通过.shift() + .ne() + .cumsum() 得到连续相同的state 的分组。

      然后,对于每个组(连续相同的state),我们使用.groupby() + .agg() 得到time 的第一个条目和time_end 的最后一个条目,如下所示:

      df['state_group'] = df['state'].ne(df['state'].shift()).cumsum()
      
      df_out = df.groupby('state_group').agg({'time': 'first', 'state': 'first', 'time_end': 'last'}).reset_index(drop=True)
      

      结果:

      print(df_out)
      
               time state    time_end
      0  12-08-2020   off  13-08-2020
      1  13-08-2020    on  16-08-2020
      2  16-08-2020   off        None
      

      仅供参考,以下临时数据帧是在上面第一行代码之后使用连续相同的state 分组创建的。我们基于此分组来聚合所需的扁平化结果。

               time state    time_end  state_group
      0  12-08-2020   off  13-08-2020            1
      1  13-08-2020    on  14-08-2020            2
      2  14-08-2020    on  15-08-2020            2
      3  15-08-2020    on  16-08-2020            2
      4  16-08-2020   off         NaN            3
      

      【讨论】:

      • @HenryEcker 我的基础 df 是使用 `df.time.shift(-1) 创建的 time_end
      • 嗯,有道理。你从第 2 步开始,我从第 1 步开始。 :)
      • @HenryEcker 对,因为time_end 列的创建是在OP 提到my question is now... 之前。所以,以此为基础。
      • 是的,这是有道理的。
      猜你喜欢
      • 2021-01-09
      • 1970-01-01
      • 1970-01-01
      • 2021-02-16
      • 2018-03-21
      • 2021-11-20
      • 2021-02-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多