stackoverflow原问答链接。
文章目录
问题: 需要把dataframe,先进行gourpby()
处理、再对结果进行排序:
"""现有数据如下:"""
# print(df)
count job source
0 2 sales A
1 4 sales B
2 6 sales C
3 3 sales D
4 7 sales E
5 5 market A
6 3 market B
7 2 market C
8 4 market D
9 1 market E
df_gb = df.groupby(['job', 'source']).agg({'count':sum})
#print(df_groupby)
count # note: 此处有“count”
job source
market A 5
B 3
C 2
D 4
E 1
sales A 2
B 4
C 6
D 3
E 7
我想要:的结果是groupby()
里边count降序排列、取每个group的前3数据:
job source #(本列count)
market A 5
D 4
B 3
sales E 7
C 6
B 4
方法一:直接使用nlargest()
df_gb = df.groupby(['job', 'source']).agg({'count':sum})
g = df_gb ['count'].groupby(level=0, group_keys=False) # 更多信息见下边备注
res = g.nlargest(3)
print(res)
# res输出结果如下:
job source #(本列count)
market A 5
D 4
B 3
sales E 7
C 6
B 4
dtype: int64
g = df_gb ['count'].groupby(level=0, group_keys=False)
- 为什么使用
df_gb['count'].groupby(level=0)
,而不是df_gb.groupby(by=['count'], level=0)
?- 为什么
.groupby()
里边需要level=0
?
因为"by"和"level"在groupby函数至少得有一个。 这里指的是job
列。- 不设置
group_keys=False
会怎样?
会有2个"job"列。 它保证了原index值在结果的group里被保留,并且没有额外level的group标签。.groupby()
里边参数by
和level
只能取其中1个。res = g.nlargest(3)
等价于
–res = g.apply(lambda x: x.order(ascending=False).head(3)
其他:
.nlargest()
似乎结果只保留单个value的结果,例如df_gb ['count']
,即使df_gb里有其他类似count的统计值也不会被保留。典型场景如Pandas.pivot_table(columns=my_column)
,下边的方法二则会保留所有的
:
方法二:sort_values()
搭配 head()
haha = df.sort_values(['job', 'count'], ascending=False).groupby('job').head(3)
print(haha)
# haha输出结果如下:
count job source # 这一次显示“列名称” & 也没有增减“列” & 也没有改变“列”的顺序
4 7 sales E
2 6 sales C
1 4 sales B
5 5 market A
8 4 market D
6 3 market B
备注:
nlargest()
在下列情况不能使用,因为没有count
字段:
df_groupby = df.groupby(['job', 'source'])['count'].sum()
print(df_groupby)
# 这里没有count,导致g = df_groupby['count']不存在。
job source
market A 5
B 3
C 2
D 4
E 1
sales A 2
B 4
C 6
D 3
E 7
groupby()
和pd.pivot_table()
的结果会删除有NaN的行的结果,这和merge()
、concat()
、join()
等函数不同,[引用链接]:
df = pd.DataFrame({'col1':[np.nan, 'match', np.nan], 'col2':[1,2,1]})
print(df.groupby('col1').sum())
# 结果如下:
col2
col1
match 2
# 而不是
col2
col1
match 2
NaN 2