熊猫如何通过标志列获得前n组

时间:2019-03-04 06:03:44

标签: python-3.x pandas

我有如下数据框。

df = pd.DataFrame({'group':[1,2,1,3,3,1,4,4,1,4], 'match': [1,1,1,1,1,1,1,1,1,1]})

   group  match
0      1      1
1      2      1
2      1      1
3      3      1
4      3      1
5      1      1
6      4      1
7      4      1
8      1      1
9      4      1

我想获得如下所示的前n个组(n = 3)。

   group  match
0      1      1
1      1      1
2      1      1
3      1      1
4      4      1
5      4      1
6      4      1
7      3      1
8      3      1

实际上,我的数据的每一行都有另一条信息要使用,因此仅对匹配项进行排序,然后提取前n个。

该怎么做?

1 个答案:

答案 0 :(得分:2)

我认为您需要每列match的前3个组-将SeriesGroupBy.value_countsGroupBy.head一起用于每组的前3个组,然后通过Index.to_frame和{{将索引转换为DataFrame 3}}:

s = df.groupby('match')['group'].value_counts().groupby(level=0).head(3).swaplevel()

df = s.index.to_frame().reset_index(drop=True).merge(df)
print (df)
   group  match
0      1      1
1      1      1
2      1      1
3      1      1
4      4      1
5      4      1
6      4      1
7      3      1
8      3      1

或者如果只需要过滤match1的值,则将DataFrame.mergeSeries.value_counts一起过滤:

s = df.loc[df['match'] == 1, 'group'].value_counts().head(3)

df = s.index.to_frame(name='group').merge(df)
print (df)
   group  match
0      1      1
1      1      1
2      1      1
3      1      1
4      4      1
5      4      1
6      4      1
7      3      1
8      3      1

使用isin和有序分类的解决方案:

#if need filter match == 1
idx = df.loc[df['match'] == 1, 'group'].value_counts().head(3).index
#if dont need filter
#idx = df.group.value_counts().head(3).index
df = df[df.group.isin(idx)]

df['group'] = pd.CategoricalIndex(df['group'], ordered=True, categories=idx)

df = df.sort_values('group')
print (df)
  group  match
0     1      1
2     1      1
5     1      1
8     1      1
6     4      1
7     4      1
9     4      1
3     3      1
4     3      1

match列的更改数据中可以最好地看出解决方案的差异:

df = pd.DataFrame({'group':[1,2,1,3,3,1,4,4,1,4,10,20,10,20,10,30,40], 
                   'match': [1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0]})

print (df)
    group  match
0       1      1
1       2      1
2       1      1
3       3      1
4       3      1
5       1      1
6       4      1
7       4      1
8       1      1
9       4      1
10     10      0
11     20      0
12     10      0
13     20      0
14     10      0
15     30      0
16     40      0

每组匹配的前3个值:

s = df.groupby('match')['group'].value_counts().groupby(level=0).head(3).swaplevel()
df1 = s.index.to_frame().reset_index(drop=True).merge(df)
print (df1)
    group  match
0      10      0
1      10      0
2      10      0
3      20      0
4      20      0
5      30      0
6       1      1
7       1      1
8       1      1
9       1      1
10      4      1
11      4      1
12      4      1
13      3      1
14      3      1

通过匹配== 1的前3个值

s = df.loc[df['match'] == 1, 'group'].value_counts().head(3)

df2 = s.index.to_frame(name='group').merge(df)
print (df2)
   group  match
0      1      1
1      1      1
2      1      1
3      1      1
4      4      1
5      4      1
6      4      1
7      3      1
8      3      1

Top3值的match列并不重要:

s = df['group'].value_counts().head(3)
df3 = s.index.to_frame(name='group').merge(df)
print (df3)
   group  match
0      1      1
1      1      1
2      1      1
3      1      1
4     10      0
5     10      0
6     10      0
7      4      1
8      4      1
9      4      1