0

0

Pandas数据框高级分组:基于阈值的动态停止策略

DDD

DDD

发布时间:2025-08-01 15:04:01

|

761人浏览过

|

来源于php中文网

原创

Pandas数据框高级分组:基于阈值的动态停止策略

本教程详细阐述了如何在Pandas中实现一种高级分组策略:根据子组的行数是否达到预设阈值,动态决定是否继续深入分组。通过迭代处理和条件筛选,本方法能够高效地对数据进行分层聚合,同时避免对小规模子组进行不必要的细化,从而得到符合特定业务逻辑的分组结果。

引言:动态分组的挑战

在数据分析中,pandas的groupby功能是进行数据聚合的核心工具。然而,在某些特定场景下,我们可能需要更灵活的分组逻辑。例如,我们希望对数据框按多列(如a, b, c)进行分组,但如果某个子组(例如,仅按a分组后)的行数少于一个预设阈值,我们就希望停止对该子组继续按b和c进行细分,而是将其作为一个整体进行统计。对于行数超过阈值的子组,则继续进行更细粒度的分组。这种动态停止分组的需求,常规的groupby操作难以直接满足。

考虑以下示例数据框:

import pandas as pd
import numpy as np

df = pd.DataFrame({'a':[1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2],
                   'b':[1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
                   'c':[1, 1, 1, 2, 2, 2, 3, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2]
                  })
print("原始数据框:")
print(df)

我们的目标是,如果某个组的行数低于阈值(例如3),则停止进一步分组。期望的输出结果如下,其中group_size表示最终组的大小:

   a  b    c  group_size
0  1  1  1.0           3  # (a=1, b=1, c=1) 组大小为3,达到阈值,停止
1  1  1  2.0           3  # (a=1, b=1, c=2) 组大小为3,达到阈值,停止
2  1  2  NaN           3  # (a=1, b=2) 组大小为3,达到阈值,停止,c列不再细分
3  2  2  2.0           9  # (a=2, b=2, c=2) 组大小为9,达到阈值,停止

可以看到,当a=1, b=2时,其子组的总行数为3(c=3一行,c=4两行),满足阈值条件。因此,对于a=1, b=2这一组,我们不再按c列进行细分,而是将其作为一个整体,其c列显示为NaN。

核心思路:迭代与条件聚合

解决这个问题的核心思路是采用迭代和条件聚合。我们从最细粒度的分组开始(即所有分组列),然后逐步“向上”聚合。在每一步迭代中:

  1. 计算当前分组级别下所有组的行数。
  2. 识别出那些行数已达到或超过阈值的组,将它们标记为“已完成”,并从待处理数据中移除。
  3. 对于那些行数仍低于阈值的组,将其保留,并在下一轮迭代中向上聚合(即减少一个分组列)。

这个过程一直持续到所有组都已达到阈值或只剩下最顶层分组列为止。

实现步骤与代码解析

下面是实现上述逻辑的Python代码及其详细解析:

thresh = 3 # 设定阈值

cols = list(df.columns) # 获取所有列作为初始分组键
s = df.value_counts()   # 使用value_counts()获取初始的最细粒度分组计数

out = [] # 用于存储每次迭代中满足条件的组

# 循环直到没有更多的分组列或所有组都已处理
while cols and len(s):
    # 根据当前 cols 进行分组并求和计数
    # s 此时是一个Series,其索引是多层索引,代表了当前的分组键
    # groupby(level=cols) 允许我们根据索引的指定层级进行分组
    s = s.groupby(level=cols).sum()

    # 找出计数小于阈值的组(这些组需要进一步向上聚合)
    m = s < thresh

    # 将计数大于等于阈值的组添加到结果列表 out
    # 这些组已经满足条件,不再需要进一步细分
    out.append(s[~m])

    # 更新 s,只保留那些计数小于阈值的组,以便在下一轮迭代中处理
    s = s[m]

    # 移除最内层的分组列,准备进行更粗粒度的分组
    # 例如,如果当前 cols 是 ['a', 'b', 'c'],则移除 'c' 变为 ['a', 'b']
    cols.pop()

# 循环结束后,s 中可能还剩下一些组(即使是最粗粒度的分组,也可能不满足阈值)
# 将这些剩余的组也添加到结果列表
out.append(s)

# 将 out 列表中的所有 Series 合并成一个 DataFrame,并重置索引
# reset_index() 会将多层索引转换为普通列
out = pd.concat([x.reset_index() for x in out])

# 重命名计数列为 'count' (根据实际需求,可改为 'group_size')
out.rename(columns={0: 'count'}, inplace=True) # value_counts() 默认计数列名为0

print("\n最终结果:")
print(out)

代码解析:

听脑AI
听脑AI

听脑AI语音,一款专注于音视频内容的工作学习助手,为用户提供便捷的音视频内容记录、整理与分析功能。

下载
  1. thresh = 3: 定义了分组的行数阈值。
  2. cols = list(df.columns): 初始化分组列,开始时包含所有列,表示最细粒度的分组。
  3. s = df.value_counts(): 这是一个高效的初始计数方法。它会计算数据框中所有唯一行组合的出现次数,并返回一个Series,其索引是多层索引,代表了每个唯一组合,值是其出现次数。
  4. out = []: 创建一个空列表,用于收集每次迭代中满足阈值条件的最终分组结果。
  5. while cols and len(s):: 循环条件。只要还有分组列需要处理(cols不为空)且还有未处理的组(s不为空),就继续循环。
  6. s = s.groupby(level=cols).sum(): 这是核心步骤。在每次迭代中,s的索引可能包含比cols更多的层级(因为它是从value_counts()开始的)。groupby(level=cols)会根据当前cols中指定的索引层级进行重新分组,并对这些组的计数进行求和。例如,如果cols是['a', 'b'],s的索引是('a', 'b', 'c'),那么此操作会将所有('a', 'b')相同的组的计数加起来。
  7. m = s < thresh: 创建一个布尔掩码,标记出那些当前计数小于阈值的组。这些组需要进一步“向上”聚合。
  8. out.append(s[~m]): 将计数大于或等于阈值的组(即~m对应的组)添加到out列表中。这些组已经满足条件,其细分到当前级别即可。
  9. s = s[m]: 更新s,只保留那些计数小于阈值的组。这些组将在下一轮迭代中,以更粗的粒度进行处理。
  10. cols.pop(): 移除cols列表中的最后一个元素。这意味着在下一轮迭代中,我们将使用更少的分组列进行聚合,从而实现“向上聚合”的效果。
  11. out.append(s): 循环结束后,s中可能还剩下一些组。这些组是即使在最粗粒度(只剩一个分组列或没有分组列)下也未能达到阈值的组。将它们全部添加到out中。
  12. pd.concat([x.reset_index() for x in out]): 最后,将out列表中收集到的所有Series(每个Series代表一个批次的结果)合并成一个大的DataFrame。reset_index()将多层索引转换为普通的数据列。

输出结果:

   a    b    c  count
0  1  1.0  1.0      3
1  1  1.0  2.0      3
2  2  2.0  2.0      9
3  1  2.0  NaN      3

与期望输出对比,结果一致。

注意事项

  1. 效率考量

    • 初始使用df.value_counts()来获取最细粒度的计数,通常比df.groupby(list(df.columns)).size()更高效,尤其是在数据量较大时。
    • 迭代过程中对s的groupby(level=cols).sum()操作,避免了对原始DataFrame进行反复的groupby和merge,从而提高了性能。
  2. 结果列的NaN值

    • 在最终结果中,例如当a=1, b=2时,c列显示为NaN。这正是我们所期望的行为。当一个组(如(a=1, b=2))的总行数达到阈值时,我们就不再关心其内部c列的具体值。在合并不同粒度的结果时,由于c列不再作为该组的区分键,其值自然会填充为NaN,表示该列在该分组级别上不再具有特定意义。
  3. 通用性

    • 此方法非常通用,可以应用于任意数量的分组列和任何预设的阈值。只需调整thresh变量和初始的df即可。
    • 分组列的顺序会影响处理的粒度,从最细到最粗(即cols.pop()会从列表末尾移除列)。确保cols列表中的列顺序符合你从最细到最粗的聚合逻辑。

总结

本教程介绍了一种在Pandas中实现高级动态分组的策略,该策略能够根据子组的行数阈值,灵活地决定是否继续深入分组。通过迭代地对数据进行聚合和筛选,我们能够高效地处理复杂的分组逻辑,并生成符合特定业务需求的分层聚合结果。这种方法不仅解决了传统groupby的局限性,还在性能上表现出色,是处理类似动态分组问题时的有力工具。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
Python 时间序列分析与预测
Python 时间序列分析与预测

本专题专注讲解 Python 在时间序列数据处理与预测建模中的实战技巧,涵盖时间索引处理、周期性与趋势分解、平稳性检测、ARIMA/SARIMA 模型构建、预测误差评估,以及基于实际业务场景的时间序列项目实操,帮助学习者掌握从数据预处理到模型预测的完整时序分析能力。

81

2025.12.04

Python 数据清洗与预处理实战
Python 数据清洗与预处理实战

本专题系统讲解 Python 在数据清洗与预处理中的核心技术,包括使用 Pandas 进行缺失值处理、异常值检测、数据格式化、特征工程与数据转换,结合 NumPy 高效处理大规模数据。通过实战案例,帮助学习者掌握 如何处理混乱、不完整数据,为后续数据分析与机器学习模型训练打下坚实基础。

34

2026.01.31

while的用法
while的用法

while的用法是“while 条件: 代码块”,条件是一个表达式,当条件为真时,执行代码块,然后再次判断条件是否为真,如果为真则继续执行代码块,直到条件为假为止。本专题为大家提供while相关的文章、下载、课程内容,供大家免费下载体验。

107

2023.09.25

append用法
append用法

append是一个常用的命令行工具,用于将一个文件的内容追加到另一个文件的末尾。想了解更多append用法相关内容,可以阅读本专题下面的文章。

349

2023.10.25

python中append的用法
python中append的用法

在Python中,append()是列表对象的一个方法,用于向列表末尾添加一个元素。想了解更多append的更多内容,可以阅读本专题下面的文章。

1080

2023.11.14

python中append的含义
python中append的含义

本专题整合了python中append的相关内容,阅读专题下面的文章了解更多详细内容。

186

2025.09.12

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

42

2026.03.13

Python异步编程与Asyncio高并发应用实践
Python异步编程与Asyncio高并发应用实践

本专题围绕 Python 异步编程模型展开,深入讲解 Asyncio 框架的核心原理与应用实践。内容包括事件循环机制、协程任务调度、异步 IO 处理以及并发任务管理策略。通过构建高并发网络请求与异步数据处理案例,帮助开发者掌握 Python 在高并发场景中的高效开发方法,并提升系统资源利用率与整体运行性能。

79

2026.03.12

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

234

2026.03.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.5万人学习

Django 教程
Django 教程

共28课时 | 5万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号