【问题标题】:How to apply a pre-condition to GroupBy or how to ignore groups with one record in GroupBy如何将前提条件应用于 GroupBy 或如何忽略 GroupBy 中具有一条记录的组
【发布时间】:2016-04-29 17:32:50
【问题描述】:

我有一组行,我想按标识符的值进行分组 - 存在于每一行中 - 然后对将成为此结果的组进行进一步的隔离处理。

我的数据框如下所示:

In [50]: df
Out[50]: 
  groupkey    b    c   d   e                date
0       C1   b1   c1  d1  e1 2014-10-26 12:13:14
1       C2  NaN   c2  d2  e2 2014-11-02 12:13:14
2       C1   b3   c3  d3  e3 2014-11-09 12:13:14
3       C1   b4  NaN  d4  e4 2014-11-16 12:13:14
4       C3   b5   c5  d5  e5 2014-11-23 12:13:14
5       C2   b6   c6  d6  e6 2014-11-30 12:13:14

如果我要按 groupkey 分组,我知道我应该只处理返回的 GroupBy

>> df.groupby('groupkey')

但是,在分组之前以及为了减少数据集大小的并行目的,我不想考虑每组只有一条记录的任何行(如果以上述方式分组)。

在我的示例中,这意味着应该省略行 4

现在,在我看来,计算每组记录的最简单方法当然是先分组,然后计算记录,如下所示:

>> df.groupby('groupkey').count()

我想我可以这样做,然后删除只有一条记录的组。

  1. 我不确定如何解决此问题,而无需手动返回并删除只有一条记录的组。

  2. 我想知道是否有办法按某些函数进行分组,让我在分组时考虑到这种情况?

感谢您的帮助

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    您想在群组上使用len filter groupby 对象:

    In [9]:
    df.groupby('groupkey').filter(lambda x: len(x) > 1)
    
    Out[9]:
      groupkey    b    c   d   e                date
    0       C1   b1   c1  d1  e1 2014-10-26 12:13:14
    1       C2  NaN   c2  d2  e2 2014-11-02 12:13:14
    2       C1   b3   c3  d3  e3 2014-11-09 12:13:14
    3       C1   b4  NaN  d4  e4 2014-11-16 12:13:14
    5       C2   b6   c6  d6  e6 2014-11-30 12:13:14
    

    【讨论】:

    • 感谢您的帮助,非常直截了当,完全符合我的要求。
    【解决方案2】:

    我认为你可以先用value_counts 过滤DataFramemapboolean indexing

    print df.groupkey.value_counts() != 1
    C1     True
    C2     True
    C3    False
    Name: groupkey, dtype: bool
    
    print df.groupkey.map(df.groupkey.value_counts() != 1)
    0     True
    1     True
    2     True
    3     True
    4    False
    5     True
    Name: groupkey, dtype: bool
    
    print df[df.groupkey.map(df.groupkey.value_counts() != 1)]
      groupkey    b    c   d   e                 date
    0       C1   b1   c1  d1  e1  2014-10-26 12:13:14
    1       C2  NaN   c2  d2  e2  2014-11-02 12:13:14
    2       C1   b3   c3  d3  e3  2014-11-09 12:13:14
    3       C1   b4  NaN  d4  e4  2014-11-16 12:13:14
    5       C2   b6   c6  d6  e6  2014-11-30 12:13:14
    

    有趣的是,它比filter 解决方案更快(len(df)=6k):

    df = pd.concat([df]*1000).reset_index(drop=True)
    
    In [21]: %timeit df[df.groupkey.map(df.groupkey.value_counts() != 1)]
    1000 loops, best of 3: 1.87 ms per loop
    
    In [22]: %timeit df.groupby('groupkey').filter(lambda x: len(x) != 1)
    100 loops, best of 3: 2.71 ms per loop
    

    【讨论】:

    • 我喜欢这个。我正在写自己的答案,但这更复杂。有什么理由使用df.groupkey 而不是df['groupkey']
    • 是一样的,也许好看。
    • 感谢您的帮助、漂亮的方法和性能加分。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-25
    • 2020-07-15
    • 2019-04-23
    • 1970-01-01
    • 2017-11-04
    • 2017-01-06
    相关资源
    最近更新 更多