当前位置: 首页 > news >正文

Pandas第四章分组

一、分组模式及其对象

1.分组的一般模式

分组操作的核心三要素:

  • 分组依据:按什么维度分组(如性别、班级、自定义条件)
  • 数据来源:要对哪些列进行计算(如身高、寿命、分数)
  • 操作:组内要执行的统计 / 变换(如均值、中位数、标准化)

通用代码模板

df.groupby(分组依据)[数据来源].使用操作

示例:按性别统计身高中位数

df = pd.read_csv('../data/learn_pandas.csv') df.groupby('Gender')['Height'].median()

2.分组依据的本质

分组依据本质是可对齐的序列 / 列表groupby会按序列的唯一值对行进行分组。

(1)常见分组依据类型

  1. 列名 / 列名列表(最常用)

    # 单维度:按性别分组 df.groupby('Gender')['Height'].mean() # 多维度:按学校+性别分组 df.groupby(['School', 'Gender'])['Height'].mean()
  2. 布尔序列 / 条件序列

    # 按体重是否超过均值分组 condition = df.Weight > df.Weight.mean() df.groupby(condition)['Height'].mean()

    结果会按True/False分成两组。

  3. 任意序列 / 列表

    import numpy as np item = np.random.choice(list('abc'), df.shape[0]) df.groupby(item)['Height'].mean()

    结果会按a/b/c分成三组。

  4. 多个序列组合

    # 按「体重条件 + 随机字母」分组 df.groupby([condition, item])['Height'].mean()

    结果是两个序列的笛卡尔积分组。

(2)分组依据的等价形式

传入列名等价于传入该列的 Series:

# 以下两种写法完全等价 df.groupby(['School', 'Gender'])['Height'].mean() df.groupby([df['School'], df['Gender']])['Height'].mean()

可以通过drop_duplicates()查看所有组的类别:

df[['School', 'Gender']].drop_duplicates()

这会列出所有「学校 + 性别」的唯一组合,也就是最终的分组。

注:

  • groupby的本质是按序列的唯一值分组,列名、条件、列表都是序列的不同形式。
  • 多维度分组 = 多个序列的组合,组是所有组合的唯一值。
  • 通用模式:df.groupby(by=...)[cols].agg(...),是 pandas 数据分析的核心工具。

3.Groupby 对象

Groupby 对象的核心属性与方法

先创建分组对象:

gb = df.groupby(['School', 'Grade'])
属性 / 方法作用示例
ngroups返回分组的总个数gb.ngroups→ 16
groups返回组名 → 组内行索引的字典gb.groups.keys()可查看所有组名
size()返回每个组的元素个数gb.size()按组统计行数
get_group()传入组名,直接提取该组的所有行gb.get_group(('Fudan University', 'Freshman'))

注意:size()在 DataFrame 中是表的总元素数,但在groupby对象中是每组的行数,这是一个易混点。

4.分组的三大操作

分组操作根据返回结果的形态,分为三类:

操作类型对应方法返回结果典型场景
聚合(Aggregation)agg()/mean()/median()/size()每组返回单个标量值统计组内均值、中位数、组容量等
变换(Transformation)transform()每组返回与原行等长的 Series组内标准化、组内填充缺失值等
过滤(Filtering)filter()返回符合条件的整组行筛选出组均值 > 80 的班级、组容量 > 10 的组等

三大操作的对应场景示例

  • 聚合:按性别统计身高的平均值 → 每组返回一个数。
  • 变换:按季节对温度做组内标准化 → 每行返回一个变换后的值,长度与原表一致。
  • 过滤:筛选出组内数学平均分 > 80 的班级 → 返回符合条件班级的所有学生行。

二、聚合函数

1. 内置聚合函数

groupby对象上直接定义了大量经过优化的内置聚合函数,优先使用(速度快、代码简洁)。

常用函数列表max/min/mean/median/count/all/any/idxmax/idxmin/mad/nunique/skew/quantile/sum/std/var/sem/size/prod

基础示例

# 1. 按性别分组,选取身高列 gb = df.groupby('Gender')['Height'] # 2. 示例1:返回每组最小值的索引(idxmin) gb.idxmin() # 输出:Gender Female→143, Male→199 # 3. 示例2:返回每组95%分位数(quantile) gb.quantile(0.95) # 输出:Gender Female→166.8, Male→185.9
多列迭代计算

当传入多列时,函数会按列独立计算:

gb = df.groupby('Gender')[['Height', 'Weight']] gb.max()

结果:

GenderHeightWeight
Female170.263.0
Male193.989.0

2. 万能聚合方法:agg()/aggregate()

aggaggregate的缩写,它能解决内置函数无法覆盖的四大问题。

(1)同时使用多个函数

传入函数名列表,结果列为多级索引(列名 × 函数名)。

gb.agg(['sum', 'idxmax', 'skew'])

结果结构:

  • 行:分组键(Female/Male)
  • 列:Height/Weight 分别对应 sum/idxmax/skew

(2)为特定列指定特定函数

传入字典(键 = 列名,值 = 函数 / 函数列表)。

gb.agg({ 'Height': ['mean', 'max'], # 身高求均值、最大值 'Weight': 'count' # 体重求计数 })

结果:

GenderHeight_meanHeight_maxWeight_count
Female159.19697170.2135
Male173.62549193.954

(3)使用自定义函数

lambda或自定义函数,参数为组内列的 Series,必须返回标量

  1. Lambda 计算极差(最大值 - 最小值):

    gb.agg(lambda x: x.mean() - x.min())
  2. 自定义复杂逻辑(对比总体均值):

    def my_func(s): # s.name 是列名(Height/Weight) return 'High' if s.mean() > df[s.name].mean() else 'Low' gb.agg(my_func)

    结果:根据组均值是否高于总体均值,返回 High/Low。

(4)聚合结果重命名

将函数位置改写为元组(新名字, 原函数),灵活定制列名。

  1. 列表形式重命名(多函数):

    gb.agg([ ('range', lambda x: x.max()-x.min()), ('my_sum', 'sum') ])
  2. 字典形式重命名(列映射):

    gb.agg({ 'Height': [('my_func', my_func), 'sum'], 'Weight': ('max', lambda x: x.max()) })

  1. 优先使用:Groupby 原生函数(mean,sum,idxmax等),速度经过优化。
  2. agg是万能钥匙
    • 用列表实现多函数同时计算
    • 用字典实现列 - 函数精准匹配
    • 用函数 / Lambda 实现自定义逻辑
    • 用元组(别名, 函数)实现结果重命名
  3. 注意点:自定义传入函数必须保证返回标量(单值)。

三、变换和过滤

1. 变换函数与transform方法

(1)变换的核心定义

  • 返回规则:变换函数必须返回与原数据 **** 同长度的序列(Series/DataFrame)。
  • 机制:“拆分 - 应用 - 合并” 中的 “应用” 阶段,将计算结果广播回原数据的每一行,保持索引和形状不变。

(2)内置变换函数

Groupby 对象支持一系列组内累计变换函数,返回同长度的序列:

函数含义
cummax()组内累计最大值
cummin()组内累计最小值
cumsum()组内累计求和
cumprod()组内累计求积
cumcount()组内计数(从 0 开始)

示例

gb = df.groupby('Gender')[['Height', 'Weight']] gb.cummax().head() # 每组内逐行累计最大值
  • 输出结果行数与原表一致,每一行展示当前行及之前的最大值。

(3)自定义变换:transform方法

transform是自定义变换的核心方法,传入的函数参数是组内的 Series,必须返回同长度的结构

示例:分组标准化(Z-Score)

对身高和体重进行组内标准化:(x−μ)/σ

# gb = df.groupby('Gender')[['Height', 'Weight']] gb.transform(lambda x: (x - x.mean()) / x.std()).head()
  • 输入:每组的 Height/Weight 序列。
  • 输出:与原表形状完全一致的标准化结果,索引保持不变。

(4)标量广播机制(特征工程常用)

transform不仅可以返回同长序列,还可以返回标量,结果会自动广播到整个组。这是特征工程中构造组级特征的关键技巧。

示例:构造组均值特征

为每一行添加所在组的身高、体重均值信息:

# gb = df.groupby('Gender')[['Height', 'Weight']] gb.transform('mean').head()

结果结构

  • 每行的值是该组(性别)的整体均值。
  • 例如 Female 组的每一行 Height 都会填充为 159.19...,Weight 填充为 47.91...。

2.组索引与过滤

(1)过滤 vs 索引(行过滤)

  • 索引 / 行过滤:对每一行单独判断,符合条件的行保留,不符合的丢弃。
  • 组过滤:对整个组判断,如果组整体满足条件(返回True),则该组所有行都保留;如果不满足(返回False),则该组所有行都被丢弃。
  • 本质:组过滤是行过滤的推广,筛选单位从「行」升级为「组」。

(2)filter方法核心用法

groupby对象提供filter()方法实现组过滤:

  • 输入:自定义函数(或 lambda),参数是当前组的完整 DataFrame,可以使用所有 DataFrame 方法 / 属性。
  • 输出:函数必须返回一个布尔值(True/False)
    • True:保留该组的所有行
    • False:丢弃该组的所有行
  • 最终结果:所有保留组的行拼接成新的 DataFrame。

示例:保留样本量 > 100 的组

# gb = df.groupby('Gender')[['Height', 'Weight']] gb.filter(lambda x: x.shape[0] > 100).head()
  • x.shape[0]:获取当前组的行数(样本量)。
  • 逻辑:只保留样本量超过 100 的组,其余组全部过滤掉。

(3)核心特点

  • 函数参数是 DataFrame:可以在函数里做复杂统计(如均值、标准差、样本量等)来决定是否保留该组。
  • 结果形状:行数可能减少(因为丢弃了部分组),但列数不变。
  • 典型场景
    • 过滤掉样本量过小的组(避免统计偏差)
    • 过滤掉组均值 / 方差不符合要求的组
    • 只保留满足特定业务条件的组

(4)总结

  • 行过滤df[condition]→ 逐行判断
  • 组过滤gb.filter(lambda x: ...)→ 逐组判断
  • filter是 pandas 分组三大操作(聚合 / 变换 / 过滤)之一,是处理分组数据的重要工具。

四、跨列分组

1. apply的引入

  • 跨列计算需求:比如 BMI 计算需要同时用到WeightHeight两列,agg只能逐列聚合,无法处理多列联动。
  • 返回标量 / Series/DataFrame 灵活适配filter只能返回布尔值,transform只能返回同长度序列,而apply可以返回任意结构。
  • 典型场景:分组后基于多列计算复合指标(如 BMI、评分公式),并返回聚合结果。

2. 基础示例:分组计算 BMI 均值

import pandas as pd def BMI(x): Height = x['Height'] / 100 # 假设身高单位是厘米,转成米 Weight = x['Weight'] BMI_value = Weight / Height**2 return BMI_value.mean() # 按 Gender 分组,传入 BMI 函数 gb = df.groupby('Gender')[['Height', 'Weight']] result = gb.apply(BMI)

结果是一个Series,索引为分组键,值为每组 BMI 均值。

3. 不同返回值类型的结果形态

返回类型结果类型索引结构示例效果
标量 / 列表Seriesagg结果一致(分组键作索引)每组返回一个值 / 列表,如lambda x: 0lambda x: [0,0]
SeriesDataFrame行索引 = 分组键,列索引 = Series 索引pd.Series([0,0], index=['a','b'])→ 生成列名为a/b的 DataFrame
DataFrameDataFrame行索引 = 分组键 + 返回 DF 行索引列索引 = 返回 DF 列索引嵌套层级最多,适合返回多维结果

4. 三种返回值的代码示例

① 标量 / 列表返回

gb = df.groupby(['Gender','Test_Number'])[['Height','Weight']] gb.apply(lambda x: 0) # 返回 Series gb.apply(lambda x: [0,0]) # 列表仍被视为标量,返回 Series(元素为列表)

② Series 返回

gb.apply(lambda x: pd.Series([0,0], index=['a','b'])) # 结果:行索引=Gender+Test_Number,列索引=a/b

③ DataFrame 返回

import numpy as np gb.apply(lambda x: pd.DataFrame( np.ones((2,2)), index=['a','b'], columns=pd.MultiIndex.from_tuples([('w','x'),('y','z')]) )) # 结果:行索引=Gender+Test_Number+a/b,列索引=多级(w/x, y/z)

注:

  • 返回标量→ 结果是Series,结构最简洁。
  • 返回 Series→ 结果是DataFrame,列由 Series 索引决定。
  • 返回 DataFrame→ 结果是多级索引 DataFrame,行 / 列都会嵌套。
  • apply是处理跨列分组计算的核心工具,尤其适合需要多列联动的复杂逻辑
http://www.cnnetsun.cn/news/1520582.html

相关文章:

  • 告别视频预览难题!QuickLookVideo让Mac文件管理效率提升3倍
  • AI作曲新浪潮:影视配乐生成的原理、实战与未来
  • 电子考古学:OpenClaw+nanobot镜像老旧格式文件抢救
  • BGE-Reranker-v2-m3镜像推荐:预装环境一键部署实战
  • 本科生论文破局指南:Paperxie AI 如何让毕业论文从「难产」变「顺产」
  • Zotero Style:文献管理效率提升的技术实现与实践指南
  • 5个必装的OpenClaw技能:百川2-13B量化模型效率工具套装
  • 为什么我的PyCharm Console显示>>>而不是In [序号]?IPython安装与配置详解
  • 7步系统优化解决方案:使用Win11Debloat实现Windows性能提升
  • 解锁光猫配置自由:中兴ONT解密工具完全指南
  • OpenClaw+nanobot超轻量级部署:5分钟搭建个人AI助手实战
  • python-flask-djangol框架的的篮球CBA联赛信息管理系统
  • Retinaface+CurricularFace镜像体验:快速部署人脸识别模型
  • 从零开始:Bibliometrix在RStudio中的安装与实战指南
  • SVG Crowbar终极指南:一键下载网页SVG矢量图形的完整解决方案
  • 像素时装锻造坊惊艳案例:基于‘赛博骑士皮甲’提示词的10组风格化输出
  • 开源像素艺术大模型教程:Pixel Dream Workshop Windows/Mac双平台部署
  • NaViL-9B惊艳效果展示:跨模态推理能力在金融财报图理解中的表现
  • 应对抖音直播间WebSocket数据抓取的技术挑战与解决方案指南
  • Inter字体系统:数字界面排版的工程化解决方案
  • 新书推荐:《尊严的颓败》在废墟之上,寻找灵魂的微光
  • SEO_网站SEO排名下降的常见原因及解决办法(344 )
  • 从理论到实践:深入解析hku-mars Lidar_IMU_Init的标定流程与激励评估
  • ScanTailor Advanced:重新定义文档数字化标准,突破传统扫描处理限制
  • CentOS 7.6 + Intel Parallel Studio XE 2017:手把手搞定VASP 5.4.4编译环境(附License激活避坑指南)
  • C标准库缓冲区溢出防范与安全编程实践
  • OpCore-Simplify:如何用四步自动化流程解决黑苹果配置的三大核心挑战
  • vLLM-v0.17.1效果案例:支持ReAct格式输出的Agent推理服务演示
  • FanControl终极指南:告别风扇噪音,打造静音高效散热系统
  • 移动端H5开发避坑指南:Vant表格组件在Vue3中的那些‘坑’与解决方案