当一个pandas数据帧按一列分组时说“版本”并且有10个不同的版本。如何绘制前三名(覆盖超过90%)并将小余数放入一个“其他”-Bucket。
data = array([
('Top1', 14),
('Top1', 3),
('Top1', 2),
('Top2', 6),
('Top2', 7),
('Other1', 1),
('Other2', 2),
],
dtype=[('Version', 'S10'),('Value', '<i4')])
df = DataFrame.from_records(data)
df.groupby('Version').sum()
返回:
Value
Version
Other1 1
Other2 2
Top1 19
Top2 13
我正在寻找
Value
Version
Others
Top1 19
Top2 13
仅为示例选择版本名称Other *和Top *。
当然,可以通过在分组后手动将类别设置为“其他”并与阈值进行比较来实现。我希望有一条捷径。
答案 0 :(得分:6)
我假设您还希望将Other
组求和,例如总共3个?
如果我的目标是赢得熊猫单线竞赛,这将是我的参赛作品:
df.replace(df.groupby('Version').sum().sort('Value', ascending=False).index[2:], 'Other').groupby('Version').sum()
Value
Version
Other 3
Top1 19
Top2 13
但这完全不可读,所以让我们分解一下:
您已经展示了如何对每个组进行求和,对此结果进行排序,并选择前2个以外的任何内容:
not_top2 = df.groupby('Version').sum().sort('Value', ascending=False).index[2:]
在此示例中,not_top2
包含Other1
和Other2
。
我们可以将Versions
替换为通用名称:
dfnew = df.replace(not_top2, 'Other')
print dfnew
Version Value
0 Top1 14
1 Top1 3
2 Top1 2
3 Top2 6
4 Top2 7
5 Other 1
6 Other 2
以上内容取代了任何列中not_top2
的内容。如果您希望此值出现在Version
以外的任何其他列中,则需要一个小子步骤。
剩下的就是再次进行原始分组:
dfnew.groupby('Version').sum()
给出了:
Value
Version
Other 3
Top1 19
Top2 13
答案 1 :(得分:2)
# number of top-n you want
n = 2
# group by & sort descending
df_sorted = (df
.groupby('Version').sum()
.sort_values('Value', ascending=False)
.reset_index()
)
# rename rows other than top-n to 'Others'
df_sorted.loc[df_sorted.index >= n, 'Version'] = 'Others'
# re-group by again
df_sorted.groupby('Version').sum()