分组聚合排序
分组、聚合、排序
准备基础数据
先构建一份包含分组、聚合特征的员工数据,后续示例都基于这份数据:
import pandas as pdimport numpy as np
# 员工基础数据(含城市、部门、薪资等分组维度)data = { "姓名": ["张三", "李四", "王五", "赵六", "钱七", "孙八"], "年龄": [20, 25, 22, 28, 30, 27], "城市": ["北京", "上海", "广州", "北京", "深圳", "北京"], "薪资": [8000, 12000, 9500, 15000, 18000, 11000], "部门": ["技术部", "销售部", "技术部", "销售部", "技术部", "销售部"]}df = pd.DataFrame(data, index=["员工1", "员工2", "员工3", "员工4", "员工5", "员工6"])# 新增薪资等级(方便分组)df["薪资等级"] = np.where(df["薪资"] > 10000, "高", "中")print("原始数据:")print(df)一、分组聚合(GroupBy + 聚合)
核心逻辑:「拆分 - 应用 - 合并」
- 拆分:把 DataFrame 按指定列(如 “城市”“部门”)分成多个小组;
- 应用:对每个小组的指定列(如 “薪资”“年龄”)执行聚合函数(如求均值、总和);
- 合并:把每个小组的聚合结果汇总成新的 DataFrame。
1. 基础分组聚合(单分组列 + 单聚合函数)
语法:df.groupby(分组列)[聚合列].聚合函数()
常用聚合函数:mean()(均值)、count()(计数)、sum()(总和)、max()(最大值)、min()(最小值)、median()(中位数)。
示例 1:按「城市」分组,统计每个城市的薪资平均值
df_city_salary = df.groupby("城市")["薪资"].mean()print("\n按城市分组的薪资均值:")print(df_city_salary)输出(按城市汇总,直观看到深圳薪资最高):
城市北京 11333.333333广州 9500.000000上海 12000.000000深圳 18000.000000Name: 薪资, dtype: float64示例 2:按「薪资等级」分组,统计每个等级的员工人数
df_grade_count = df.groupby("薪资等级")["姓名"].count()print("\n按薪资等级分组的员工人数:")print(df_grade_count)输出(高薪资等级有 4 人,中等级 2 人):
薪资等级中 2高 4Name: 姓名, dtype: int642. 多聚合函数(agg)
如果想对同一列同时执行多个聚合操作(比如既看均值,又看最大值),用 agg() 更高效。
示例:按「部门」分组,统计薪资的均值、最大值、总和
df_dept_salary = df.groupby("部门")["薪资"].agg(["mean", "max", "sum"])# 重命名列(更易读)df_dept_salary.columns = ["薪资均值", "薪资最大值", "薪资总和"]print("\n按部门分组的薪资统计:")print(df_dept_salary)输出(销售部均值略高,技术部总和更高):
薪资均值 薪资最大值 薪资总和部门技术部 11833.333333 18000 35500销售部 12666.666667 15000 380003. 多列分组 + 多列聚合
更复杂的场景:按「城市 + 部门」双维度分组,同时统计年龄和薪资。
df_city_dept = df.groupby(["城市", "部门"]).agg({ "年龄": "median", # 年龄取中位数 "薪资": "sum" # 薪资取总和})print("\n按城市+部门分组的统计:")print(df_city_dept)输出(精准定位 “北京 - 销售部” 的薪资总和、年龄中位数):
年龄 薪资城市 部门北京 技术部 20 8000 销售部 27.5 26000广州 技术部 22 9500上海 销售部 25 12000深圳 技术部 30 18000二、排序操作(Sort)
排序分为「按值排序」(最常用)和「按索引排序」,核心是调整数据的展示顺序,让结果更易读。
1. 按值排序(sort_values)
核心语法:df.sort_values(by=列名, ascending=True/False, na_position="last")
by:指定排序的列(传列表可实现多列排序);ascending:True= 升序(默认),False= 降序;na_position:缺失值位置(last= 放最后,first= 放最前)。
示例 1:按「薪资」降序排序(从高到低)
df_salary_desc = df.sort_values(by="薪资", ascending=False)print("\n按薪资降序排序:")print(df_salary_desc[["姓名", "城市", "薪资"]]) # 只展示关键列输出(钱七薪资最高,张三最低):
姓名 城市 薪资员工5 钱七 深圳 18000员工4 赵六 北京 15000员工2 李四 上海 12000员工6 孙八 北京 11000员工3 王五 广州 9500员工1 张三 北京 8000示例 2:多列排序(先按「城市」升序,再按「年龄」降序)
df_multi_sort = df.sort_values(by=["城市", "年龄"], ascending=[True, False])print("\n按城市升序、年龄降序排序:")print(df_multi_sort[["姓名", "城市", "年龄", "薪资"]])输出(同一城市内,年龄大的排前面):
姓名 城市 年龄 薪资员工4 赵六 北京 28 15000员工6 孙八 北京 27 11000员工1 张三 北京 20 8000员工3 王五 广州 22 9500员工2 李四 上海 25 12000员工5 钱七 深圳 30 180002. 按索引排序(sort_index)
如果想按行索引(如 “员工 1”“员工 2”)排序,用 sort_index。
df_index_sort = df.sort_index(ascending=False) # 索引降序(员工6→员工1)print("\n按索引降序排序:")print(df_index_sort[["姓名", "薪资"]])输出:
姓名 薪资员工6 孙八 11000员工5 钱七 18000员工4 赵六 15000员工3 王五 9500员工2 李四 12000员工1 张三 8000三、分组 + 排序 结合使用(实战常用)
实际分析中,常先分组聚合,再对聚合结果排序,让统计结果更直观。
示例:按城市分组统计薪资均值,再按均值降序排序
# 1. 分组聚合:按城市算薪资均值df_city_salary = df.groupby("城市")["薪资"].mean()# 2. 排序:按均值降序df_city_salary_sorted = df_city_salary.sort_values(ascending=False)print("\n按城市分组的薪资均值(降序):")print(df_city_salary_sorted)输出(快速看出深圳 > 上海 > 北京 > 广州的薪资水平):
城市深圳 18000.000000上海 12000.000000北京 11333.333333广州 9500.000000Name: 薪资, dtype: float64总结
- 分组聚合:核心是「按类别汇总统计」,用
groupby()指定分组列,配合agg()/ 聚合函数(mean/count/max 等)实现单 / 多维度统计; - 排序操作:按值排序用
sort_values()(指定by列,控制升 / 降序),按索引排序用sort_index(); - 组合技巧:分组聚合后对结果排序,能快速突出核心结论(如哪个城市薪资最高、哪个部门人均薪资更高)。

















