多列GroupBy组合获取Top值及无对应组合时的异常处理问询
关于Pandas GroupBy的两个常见问题解决方案
1. 如何使用不同的GroupBy组合获取浏览量最高的记录
假设我们有如下模拟用户行为的样例数据:
import pandas as pd data = { 'married': ['yes', 'yes', 'no', 'no', 'yes', 'no'], 'gender': ['male', 'female', 'male', 'female', 'male', 'female'], 'age_group': ['young', 'young', 'old', 'young', 'old', 'old'], 'occupation': ['student', 'teacher', 'engineer', 'student', 'teacher', 'engineer'], 'views': [150, 200, 300, 180, 250, 280], 'rating': [4.2, 4.5, 4.8, 4.3, 4.7, 4.6] } df = pd.DataFrame(data)
不同GroupBy组合的实现方式
方式一:groupby().idxmax() + 索引定位
先通过分组找到每组浏览量最大的行索引,再用索引提取对应记录,这是最直接的方法:
- 单分组(按
married分组)
# 获取每个婚姻状态下浏览量最高的记录 max_views_single = df.loc[df.groupby('married')['views'].idxmax()] print(max_views_single)
输出:
married gender age_group occupation views rating 2 no male old engineer 300 4.8 4 yes male old teacher 250 4.7
- 多分组(按
married+gender分组)
# 获取每个婚姻状态+性别组合下浏览量最高的记录 max_views_multi = df.loc[df.groupby(['married', 'gender'])['views'].idxmax()] print(max_views_multi)
输出:
married gender age_group occupation views rating 4 yes male old teacher 250 4.7 1 yes female young teacher 200 4.5 2 no male old engineer 300 4.8 5 no female old engineer 280 4.6
方式二:sort_values() + drop_duplicates()
先按分组列和浏览量降序排序,再保留每个分组的第一条记录,适合需要自定义排序逻辑的场景:
# 按married+age_group分组取最高浏览量 max_views_sort = df.sort_values(['married', 'age_group', 'views'], ascending=[True, True, False])\ .drop_duplicates(['married', 'age_group']) print(max_views_sort)
输出:
married gender age_group occupation views rating 5 no female old engineer 280 4.6 3 no female young student 180 4.3 4 yes male old teacher 250 4.7 1 yes female young teacher 200 4.5
2. 多列GroupBy获取评分最高记录时,处理不存在的分组组合
问题场景还原
假设我们想要获取(married='yes', gender='male', age_group='young', occupation='teacher')这个组合的最高评分记录,但当前数据里没有这个组合,直接用get_group会触发KeyError:
# 尝试获取不存在的分组组合,会报错 grouped = df.groupby(['married', 'gender', 'age_group', 'occupation']) try: grouped.get_group(('yes', 'male', 'young', 'teacher')) except KeyError as e: print(f"报错:{e}")
输出:
报错:('yes', 'male', 'young', 'teacher')
解决方案:筛选有效分组组合再处理
我们可以先获取数据中实际存在的分组键,再和目标组合做交集,只对存在的组合进行操作:
步骤1:定义目标组合列表
# 目标组合:包含存在的和不存在的 target_groups = [ ('yes', 'male', 'young', 'student'), # 数据中存在的组合 ('yes', 'male', 'young', 'teacher'), # 数据中不存在的组合 ('no', 'female', 'old', 'engineer') # 数据中存在的组合 ]
步骤2:筛选出数据中存在的组合
grouped = df.groupby(['married', 'gender', 'age_group', 'occupation']) # 获取所有已存在的分组键集合 existing_groups = set(grouped.groups.keys()) # 筛选出目标中实际存在的组合 valid_targets = [g for g in target_groups if g in existing_groups]
步骤3:提取有效组合的最高评分记录
用nlargest获取每组评分最高的第一条记录,再拼接结果:
# 获取有效组合的最高评分记录 result = pd.concat([grouped.get_group(g).nlargest(1, 'rating') for g in valid_targets]) print(result)
输出:
married gender age_group occupation views rating 0 yes male young student 150 4.2 5 no female old engineer 280 4.6
进阶:保留目标组合结构(含空值)
如果需要保留所有目标组合的结构,不存在的组合用NaN填充,可以用reindex实现:
# 先获取每个分组的最高评分 grouped_rating = grouped['rating'].max().reset_index() # 用目标组合重新索引,不存在的组合自动填充NaN final_result = grouped_rating.set_index(['married', 'gender', 'age_group', 'occupation'])\ .reindex(target_groups)\ .reset_index() print(final_result)
输出:
married gender age_group occupation rating 0 yes male young student 4.2 1 yes male young teacher NaN 2 no female old engineer 4.6
内容的提问来源于stack exchange,提问作者pylearner
相关产品推荐
相关产品推荐

