熊猫按多列分组,然后选择前n行

时间:2019-04-28 06:01:34

标签: python pandas

我具有以下结构的Pandas DataFrame

file,page_num,val,cls
f1,1,v1,c1
f1,1,v2,c2
f1,1,v3,c2
f1,1,v4,c2     # not required
f1,2,v5,c1
f1,2,v6,c2
f2,1,v7,c1
f2,1,v8,c2
f2,1,v9,c2
f2,1,v10,c2    # not required
f2,2,v11,c1
f2,2,v12,c2

我需要为two中的每个cls找到c2 page_num的前file行。其他(cls)类应保持不变。

所需的输出

file,page_num,val,cls
f1,1,v1,c1
f1,1,v2,c2
f1,1,v3,c2
f1,2,v5,c1
f1,2,v6,c2
f2,1,v7,c1
f2,1,v8,c2
f2,1,v9,c2
f2,2,v11,c1
f2,2,v12,c2

我正在尝试选择c2以外的所有类,然后使用以下内容查找c2所需的那些行。

df = pd.read_csv('sample_f.csv')

df1 = df[df.cls == 'c2'].groupby(['file', 'page_num'])
df2 = df1.apply(lambda x: x.sort_values(['cls']))
df3 = df2.reset_index(drop=True)

df = df.loc[(df.cls !=c2) & (??)]

2 个答案:

答案 0 :(得分:3)

您可以将headgroupby结合使用,然后与其余数据框串联,因此假设您需要在每个组中找到前两个val

top_2 = (
    df[df['cls'] == 'c2']
    .sort_values('val', ascending=False)
    .groupby(['file', 'page_num'])
    .head(2)
    .reset_index()
)
rest = df[df['cls'] != 'c2']
final_df = pd.concat([top_2, rest])

编辑:我添加了val排序,因为从这个问题尚不清楚数据框是否已经排序。)

答案 1 :(得分:1)

这类似于刚刚发布的答案。但是,可以的,您可以使用head

import pandas as pd
from io import StringIO
df = pd.read_csv(StringIO("""file,page_num,val,cls
f1,1,v1,c1
f1,1,v2,c2
f1,1,v3,c2
f1,1,v4,c2     
f1,2,v5,c1
f1,2,v6,c2
f2,1,v7,c1
f2,1,v8,c2
f2,1,v9,c2
f2,1,v10,c2    
f2,2,v11,c1
f2,2,v12,c2"""))
df.cls = df.cls.str.strip()
keep = df[df.cls == 'c2'].groupby(['file', 'page_num']).head(2).index
df.loc[df.loc[df.cls != 'c2'].index | keep]

输出:

   file  page_num  val cls
0    f1         1   v1  c1
1    f1         1   v2  c2
2    f1         1   v3  c2
4    f1         2   v5  c1
5    f1         2   v6  c2
6    f2         1   v7  c1
7    f2         1   v8  c2
8    f2         1   v9  c2
10   f2         2  v11  c1
11   f2         2  v12  c2