【问题标题】:group by a dataframe by values that are just less than a second off - pandas按数据框按不到一秒的值分组 - 熊猫
【发布时间】:2019-05-11 01:39:23
【问题描述】:

假设我有一个如下的熊猫数据框:

>>> df=pd.DataFrame({'dt':pd.to_datetime(['2018-12-10 16:35:34.246','2018-12-10 16:36:34.243','2018-12-10 16:38:34.216','2018-12-10 16:42:34.123']),'value':[1,2,3,4]})
>>> df
                       dt  value
0 2018-12-10 16:35:34.246      1
1 2018-12-10 16:36:34.243      2
2 2018-12-10 16:38:34.216      3
3 2018-12-10 16:42:34.123      4
>>> 

我想按'dt' 列对这个数据框进行分组,但我想以一种它认为小于一秒不同的值是相同的方式对它进行分组,在对那些我想总结的分组之后'value' 列基于每个组,并且我希望两个数据帧保持相同的长度,因此小于一秒的差异值将全部是重复值,我到目前为止尝试过:

>>> df.groupby('dt',as_index=False)['value'].sum()
                       dt  value
0 2018-12-10 16:35:34.246      1
1 2018-12-10 16:36:34.243      2
2 2018-12-10 16:38:34.216      3
3 2018-12-10 16:42:34.123      4
>>> 

但如您所见,数据框并没有改变,因为它按等效的 'dt' 列值分组。

我想要的输出是:

                       dt  value
0 2018-12-10 16:35:34.246      3
1 2018-12-10 16:36:34.243      3
2 2018-12-10 16:38:34.216      3
3 2018-12-10 16:42:34.123      4

【问题讨论】:

    标签: python pandas dataframe sum pandas-groupby


    【解决方案1】:

    蛮力解决方案是获取您的 datetime 系列和每个 datetime 值之间的绝对差,然后与阈值进行比较:

    # data from @StephenCowley
    
    threshold = pd.Timedelta(seconds=1)
    
    df['val'] = [df.loc[(df['dt'] - t).abs() < threshold, 'value'].sum()
                 for t in df['dt']]
    
    print(df)
    
                           dt  value  val
    0 2018-12-10 16:35:34.246      1    3
    1 2018-12-10 16:35:34.243      2    3
    2 2018-12-10 16:38:34.216      3    3
    3 2018-12-10 16:42:34.123      4    4
    

    【讨论】:

    • 啊,救了我,非常感谢这个世界级的解决方案,被接受并点赞!!!
    【解决方案2】:

    (假设您的意思是前两个具有相同的分钟值。)

    我不确定如何使用 groupby,但这里的结果相同:

    df=pd.DataFrame({'dt':pd.to_datetime(['2018-12-10 16:35:34.246',
                                          '2018-12-10 16:35:34.243',
                                          '2018-12-10 16:38:34.216',
                                          '2018-12-10 16:42:34.123']),
                                          'value':[1,2,3,4]})
    
                # Select the rows that are greater than a second less
                # And less than a second more
                # Get their value columns and sum them
    df['val'] = [df[(df.dt>t-pd.Timedelta(seconds=1))&
                    (df.dt<t+pd.Timedelta(seconds=1))]['value'].sum()
                 for t in df.dt]
    
                           dt  value  val
    0 2018-12-10 16:35:34.246      1    3
    1 2018-12-10 16:35:34.243      2    3
    2 2018-12-10 16:38:34.216      3    3
    3 2018-12-10 16:42:34.123      4    4
    

    作为旁注,我想用groupby 做同样的事情,但我不知道如何让它工作。您可以将函数传递给groupby 方法。如果您选择走那条路线,请注意该功能是接收 Dataframe 的索引。让我觉得使用 groupby 会很困难,因为我不知道一行可以属于多个组...

    【讨论】:

      猜你喜欢
      • 2017-10-17
      • 2018-02-01
      • 2017-07-08
      • 2013-02-28
      • 2016-06-04
      • 1970-01-01
      • 2019-10-14
      • 2022-07-15
      • 2021-08-11
      相关资源
      最近更新 更多