python - 如何选择两组中的前 N 个并将第二组的其余部分聚合到 Pandas 的“其他”中?
问题描述
我有一个包含产品、价格、类别和县的数据。我使用此代码来计算每个县每个类别的产品数量:
df_count = df.groupby(['County','Category']).size().reset_index(name='counts')
我的数据框现在看起来像这样:
县 | 类别 | 计数 | |
---|---|---|---|
0 | 布莱金厄 | 配饰和手表 | 35 |
1 | 布莱金厄 | 音频视频 | 101 |
2 | 布莱金厄 | 自行车 | 78 |
3 | 布莱金厄 | 船用零件和配件 | 65 |
4 | 布莱金厄 | 船 | 143 |
... | ... | ... | ... |
657 | 东约特兰 | 雪地车零件和配件 | 2 |
658 | 东约特兰 | 雪地摩托 | 5 |
659 | 东约特兰 | 运动休闲设备 | 335 |
660 | 东约特兰 | 工具 | 102 |
661 | 东约特兰 | 卡车和建筑 | 66 |
662行×3列
有21个县32个大类。计数是一个类别中的产品数量。在一个县,并非所有类别都是必需的。
我想要一个新的数据框,其中包含每个县的前 N 个(例如 2 个)最大类别,并将其余部分汇总到“其他”中。我希望每个县都有这个,它看起来像这样:
县 | 类别 | 计数 |
---|---|---|
布莱金厄 | 船 | 143 |
布莱金厄 | 音频视频 | 101 |
布莱金厄 | 其他 | 178 |
... | ... | ... |
东约特兰 | 运动休闲设备 | 335 |
东约特兰 | 工具 | 102 |
东约特兰 | 其他 | 175 |
我看过以前的帖子对数组做了类似的事情
如何将 Top N 之外的“剩余”结果分组到 Pandas 的“其他”中
在 pandas df 中对前 N 进行排序并将“其他”分组
并尝试了这个
# group by & sort descending
df_sorted=df_count.groupby(['County','Category']).sum().sort_values('counts', ascending=False).reset_index()
# rename rows other than top-n to 'Others'
x_sorted.groupby('County').loc[x_sorted.index >=3, 'Category'] = 'Others'
和这个
df_count.sort_values(by=['counts'], ascending=False).groupby('County').head(2).sort_values(by=['County']).reset_index(drop=True)
#not_top2 = df.groupby('Version').sum().sort('Value', ascending=False).index[2:]
not_top2 = x.groupby(['County','Category']).sum().sort_values('counts', ascending=False).index[2:]
dfnew = x.replace(not_top2, 'Other')
dfnew.groupby(['County','Category']).sum()
但没有成功获得所需的输出。
非常感谢任何帮助或指导!
解决方案
您可以使用以下步骤序列来获得最终输出,我认为这相当简单。
为了使其易于理解,我将在代码和每行输出中添加注释。
# Grab top 2 largest caterogies of each country
top_two = df.groupby('County').apply(lambda x: x.nlargest(2, 'counts')).reset_index(drop=True)
>>> top_two
County Category counts
0 Blekinge Boats 143
1 Blekinge Audio & video 101
2 Östergötland Sports & leisure equipment 335
3 Östergötland Tools 102
# Create a dataframe with the rest of the information
df_others = df.append(df.merge(top_two,'inner')).drop_duplicates(keep=False)
>>> df_others
County Category counts
0 Blekinge Accessories & watches 35
2 Blekinge Bicycles 78
3 Blekinge Boat parts & accessories 65
5 Östergötland Snowmobile parts & accessories 2
6 Östergötland Snowmobiles 5
9 Östergötland Trucks & construction 66
# Groupby country and Sum and assign 'others' under Category in the df_others dataframe
df_others = df_others.groupby('County')['counts'].sum().reset_index()
df_others['Category'] = 'Others'
>>> df_others
County counts Category
0 Blekinge 178 Others
1 Östergötland 73 Others
最后,concat()
获得最终输出的两个数据框:
res = pd.concat([top_two,df_others]).sort_values('County').reset_index(drop=True)
>>> res
County Category counts
0 Blekinge Boats 143
1 Blekinge Audio & video 101
2 Blekinge Others 178
3 Östergötland Sports & leisure equipment 335
4 Östergötland Tools 102
5 Östergötland Others 73
如果有不清楚的地方请回来。
推荐阅读
- angular - 初始化一个数组后,它告诉我他在 promise 函数的“then”中是未定义的
- ruby - 最大回文乘积问题的递归堆栈级别太深(Project Euler)
- asp.net-identity - 将身份用户对象传递给 AuthorizationFilterAttribute
- react-native - React Native Navigation v2 增加 topBar 高度
- php - 在laravel中添加两个整数
- regex - 如何使用 ruby 匹配字符串?
- scala - 将 Spark 中的行与现有列一起展平
- javascript - 如何有效地从具有多个页面的巨大 api 中提取数据
- flutter - 如何在飞镖中访问子类的变量
- pandas - 将随机日期时间添加到时间戳