Python pandas - 基于groupby选择行

Ant*_*ith 5 python group-by pandas

我有一个这样的示例表:

数据框:df

Col1     Col2    Col3    Col4
A   1   10  i
A   1   11  k
A   1   12  a
A   2   10  w
A   2   11  e
B   1   15  s
B   1   16  d
B   2   21  w
B   2   25  e
B   2   36  q
C   1   23  a
C   1   24  b
Run Code Online (Sandbox Code Playgroud)

我试图获取记录数量较少的组(Col1、Col2)的所有记录/行,并跳过那些只有 1 条记录的组(在本例中 Col1 = 'C')。因此,输出如下:

A   2   10  w
A   2   11  e
B   1   15  s
B   1   16  d
Run Code Online (Sandbox Code Playgroud)

因为组 (A,2) 有 2 条记录,而组 (A,1) 有 3 条记录。

我尝试从不同角度解决这个问题,但似乎无法得到我需要的结果。我可以使用 groupby、filter 和 agg 的组合来找到我需要的组,但现在如何将其用作 df 上的选择过滤器?在花了很多时间之后,我什至不确定该方法是否正确,因为它看起来过于复杂。我确信有一个优雅的解决方案,但我只是看不到它。任何有关如何解决此问题的建议将不胜感激。

我用这个来获取我想要显示行的组:

    groups = df.groupby(["Col1, Col2"])["Col2"].agg({'no':'count'})
filteredGroups = groups.groupby(level=0).filter(lambda group: group.size > 1)
    print filteredGroups.groupby(level=0).agg('idxmin')
Run Code Online (Sandbox Code Playgroud)

第二行是考虑那些可能只有一条记录的组,因为我不想考虑这些组。老实说,我尝试了很多变化和方法,但最终没有给我想要的结果。我发现所有答案都不是空话,所以至少我不觉得我对这个问题思考过度。

Joh*_*hnE 4

df['sz'] = df.groupby(['Col1','Col2'])['Col3'].transform("size")

df['rnk']     = df.groupby('Col1')['sz'].rank(method='min')
df['rnk_rev'] = df.groupby('Col1')['sz'].rank(method='min',ascending=False)

df.loc[ (df['rnk'] == 1.0) & (df['rnk_rev'] != 1.0) ]

      Col1  Col2  Col3 Col4  sz  rnk  rnk_rev
3    A     2    10    w   2  1.0      4.0
4    A     2    11    e   2  1.0      4.0
5    B     1    15    s   2  1.0      4.0
6    B     1    16    d   2  1.0      4.0
Run Code Online (Sandbox Code Playgroud)

编辑:将“计数”更改为“大小”(如 @Marco Spinaci 的答案),这在本例中并不重要,但如果存在缺失值,则可能会重要。

为了清楚起见,以下是删除所选行之前 df 的样子。

   Col1  Col2  Col3 Col4  sz  rnk  rnk_rev
0     A     1    10    i   3  3.0      1.0
1     A     1    11    k   3  3.0      1.0
2     A     1    12    a   3  3.0      1.0
3     A     2    10    w   2  1.0      4.0
4     A     2    11    e   2  1.0      4.0
5     B     1    15    s   2  1.0      4.0
6     B     1    16    d   2  1.0      4.0
7     B     2    21    w   3  3.0      1.0
8     B     2    25    e   3  3.0      1.0
9     B     2    36    q   3  3.0      1.0
10    C     1    23    a   2  1.0      1.0
11    C     1    24    b   2  1.0      1.0
Run Code Online (Sandbox Code Playgroud)