【问题标题】:doing group on time column and summing up only unique values在时间列上进行分组并仅总结唯一值
【发布时间】:2020-06-17 14:16:26
【问题描述】:

我有一个带有 time, host, value 列的 pandas df

数据如下

time          host     value
14:00:00      inf1     5000
14:00:00      inf2     2000
14:01:00      inf1     5000
14:01:00      inf1     5000
14:01:00      inf2     2000

我想使用以下代码按时间对它们进行分组:-

df.set_index('time').groupby([pd.Grouper(freq='1Min')]).sum()

但我只想总结唯一主机并忽略任何重复的主机。我想要的输出是

    time          sum     
    14:00:00      7000     
    14:01:00      7000     

而不是:-

time          sum     
14:00:00      7000     
14:01:00      12000 

我想在 groupby 期间忽略重复的主机。

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    第一个想法是按Grouperkey='time' 和列hostGroupBy.first 进行分组,然后按秒求和:

    df = (df.groupby(['host', pd.Grouper(key='time',freq='1Min')])['value']
            .first()
            .sum(level=1)
            .reset_index(name='sum')
            )
    
    print (df)
          time   sum
    0 14:00:00  7000
    1 14:01:00  7000
    

    如果只有几分钟的时间,另一种解决方案,因此可以通过hosttimes 通过DataFrame.drop_duplicates 删除重复项:

    df = (df.drop_duplicates(subset=['host','time'])
            .groupby([pd.Grouper(key='time',freq='1Min')])['value']
            .sum()
            .reset_index(name='sum'))
    
    print (df)
          time   sum
    0 14:00:00  7000
    1 14:01:00  7000
    

    df = (df.drop_duplicates(subset=['host','time'])
            .groupby('time')['value']
            .sum()
            .reset_index(name='sum'))
    
    print (df)
          time   sum
    0 14:00:00  7000
    1 14:01:00  7000
    

    每组删除重复项的解决方案也是可能的,但如果数据量大,速度会很慢:

    df = (df.groupby([pd.Grouper(key='time',freq='1Min')])
            .apply(lambda x: x.loc[~x['host'].duplicated(), 'value'].sum())
            .reset_index(name='sum'))
    
    print (df)
          time   sum
    0 14:00:00  7000
    1 14:01:00  7000
    

    【讨论】:

    • 我认为语法明智,先删除重复项然后求和可能更具可读性;因此,避免使用apply,即df.drop_duplicates(subset=['host', 'time']).groupby([pd.Grouper(key='time',freq='1Min')]).sum()
    • @GeneBurinsky - 也有必要删除 time 的欺骗,编辑答案。谢谢。
    • @jezrael 您最初发布的答案,这有什么问题,因为 eitw workign 对我来说...df = (df.groupby([pd.Grouper(key='time',freq=' 1Min')]) .apply(lambda x: x.loc[~x['host'].duplicated(), 'value'].sum()) .reset_index(name='sum'))
    • @abhi - 没有错,只是像另一个答案一样慢。添加到答案。
    • @jezrael 非常感谢您澄清这一点,因为我会牢记这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-20
    相关资源
    最近更新 更多