如何基于DataFrame列条件实现两种规则的分组排序
问题描述
现有如下结构的DataFrame:
Company Company Code Product Code Rating Monster MNTR MNTR/Headphone1 3.2 Monster MNTR MNTR/Headphone2 3.9 Monster MNTR MNTR/Headphone3 NaN Monster MNTR MNTR/Earbuds1 3.5 Bose BOSE BOSE/Headphone1 4.0 Bose BOSE BOSE/Earbuds1 NaN Bose BOSE BOSE/Earbuds2 2.8 Apple APLE APLE/Headphone1 4.5 Sony SONY SONY/Headphone1 3.5 Sony SONY SONY/Headphone2 4.8 Sony SONY SONY/Earbuds1 3.0 Beats BEAT BEAT/Headphone1 3.5 Beats BEAT BEAT/Headphone2 3.7
需求规则
- 若某公司存在Rating≥4.0的产品,将该公司所有产品置于结果顶部,按Rating排序但保留组内Product Code的原始顺序及公司的整体分组;
- 若公司无任何产品Rating≥4.0,则按Company Code的字母顺序进行分组排序。
期望结果
Company Company Code Product Code Rating Sony SONY SONY/Headphone1 3.5 Sony SONY SONY/Headphone2 4.8 Sony SONY SONY/Earbuds1 3.0 Apple APLE APLE/Headphone1 4.5 Bose BOSE BOSE/Headphone1 4.0 Bose BOSE BOSE/Earbuds1 NaN Bose BOSE BOSE/Earbuds2 2.8 Beats BEAT BEAT/Headphone1 3.5 Beats BEAT BEAT/Headphone2 3.7 Monster MNTR MNTR/Headphone1 3.2 Monster MNTR MNTR/Headphone2 3.9 Monster MNTR MNTR/Headphone3 NaN Monster MNTR MNTR/Earbuds1 3.5
用户尝试拆分DataFrame后合并,但不知道后续分组排序的操作:
condition = df['Rating'] >= 4.0 df_upper = df.loc[condition] df_lower = df.loc[~condition] ... df_merge = pd.concat([df_upper, df_lower], ignore_index=True)
解决方案
不需要拆分DataFrame,直接通过新增辅助列实现排序逻辑,步骤如下:
- 新增公司级辅助列
标记有高评分产品的公司,并记录公司最高评分,用于后续排序:
# 按公司分组,生成标记和最高评分数据 company_info = df.groupby('Company Code').agg( has_high_rating=('Rating', lambda x: x.ge(4.0).any()), max_rating=('Rating', 'max') ).reset_index() # 将辅助信息合并回原DataFrame df = df.merge(company_info, on='Company Code', how='left')
- 按规则排序
设置多优先级排序规则,同时保留组内原始顺序:
# 执行排序:高评分公司优先→公司最高评分降序→无高评分公司按代码升序→保留原始行顺序 df_sorted = df.sort_values( by=['has_high_rating', 'max_rating', 'Company Code', df.index], ascending=[False, False, True, True] ).drop(columns=['has_high_rating', 'max_rating']) # 移除辅助列
- 重置索引(可选)
如果需要清空原索引,执行:
df_sorted = df_sorted.reset_index(drop=True)
运行后即可得到符合要求的结果。
内容的提问来源于stack exchange,提问作者Karma
相关产品推荐
相关产品推荐

