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