0

0

Python怎样实现数据聚合?groupby方法

絕刀狂花

絕刀狂花

发布时间:2025-07-02 19:06:02

|

338人浏览过

|

来源于php中文网

原创

groupby方法是python中pandas库实现数据聚合的核心工具。1. 它基于“分、应用、合”(split-apply-combine)的思想,将数据按一个或多个键拆分成组,对每组独立执行聚合操作如求和、计数、平均值等。2. 使用时通常需要一个dataframe,并指定分组键,例如可计算每个地区的总销售额或每种产品在不同地区的平均销售额。3. 支持多列聚合、自定义聚合函数及命名聚合,提升灵活性与结果可读性。4. 在处理大规模数据时需注意内存消耗、聚合函数选择及分组键的数据类型优化,必要时可采用分布式框架。5. 高级用法包括transform()进行数据变换、filter()筛选组数据及apply()实现复杂逻辑,分别对应不同的应用场景。6. 与sql的group by相比,核心理念一致但语法和功能有所差异,groupby更灵活且支持更多高级操作,同时可通过reset_index()等方法实现sql等效查询。

Python怎样实现数据聚合?groupby方法

Python中实现数据聚合,pandas库的groupby方法是核心工具,它允许你根据一个或多个键将数据拆分成组,然后对每个组独立地执行聚合操作,比如求和、计数、平均值等,极大简化了复杂数据分析。它不仅仅是简单的数据汇总,更是一种“分而治之”的思维体现,能帮助我们从数据中挖掘出更深层次的洞察。

Python怎样实现数据聚合?groupby方法

解决方案

pandasgroupby方法是处理聚合任务的瑞士军刀。要使用它,你通常需要一个DataFrame,然后指定一个或多个列作为分组的键。

Python怎样实现数据聚合?groupby方法

想象一下,我们有一份销售数据,包含了产品、地区和销售额。如果我想知道每个地区总共卖了多少钱,或者每种产品在不同地区的平均销售额,groupby就能派上大用场。

立即学习Python免费学习笔记(深入)”;

import pandas as pd
import numpy as np

# 模拟一份销售数据
data = {
    '地区': ['华东', '华南', '华东', '华北', '华南', '华东', '华北', '华南'],
    '产品': ['A', 'B', 'A', 'C', 'B', 'C', 'A', 'A'],
    '销售额': [100, 150, 120, 80, 200, 90, 110, 130],
    '销量': [10, 15, 12, 8, 20, 9, 11, 13]
}
df = pd.DataFrame(data)
print("原始数据:")
print(df)
print("-" * 30)

# 最基础的用法:按“地区”分组,计算每个地区的总销售额
print("按地区计算总销售额:")
region_sales = df.groupby('地区')['销售额'].sum()
print(region_sales)
print("-" * 30)

# 多列聚合:按“地区”和“产品”分组,计算销售额总和与销量平均值
print("按地区和产品计算销售额总和与销量平均值:")
multi_agg = df.groupby(['地区', '产品']).agg({
    '销售额': 'sum',
    '销量': 'mean'
})
print(multi_agg)
print("-" * 30)

# 也可以对多个列应用同一个聚合函数
print("对多个列应用同一个聚合函数:")
multi_col_same_agg = df.groupby('地区')[['销售额', '销量']].sum()
print(multi_col_same_agg)
print("-" * 30)

# 自定义聚合函数:例如,计算每个地区销售额的标准差
print("自定义聚合函数(销售额标准差):")
region_std = df.groupby('地区')['销售额'].apply(lambda x: np.std(x, ddof=1)) # ddof=1 for sample standard deviation
print(region_std)
print("-" * 30)

# 命名聚合:让聚合结果列名更清晰
print("命名聚合:")
named_agg = df.groupby('地区').agg(
    总销售额=('销售额', 'sum'),
    平均销量=('销量', 'mean'),
    销售额计数=('销售额', 'count')
)
print(named_agg)
print("-" * 30)

groupby的核心在于“分、应用、合”(Split-Apply-Combine)这个思想。它首先根据你指定的键将数据“拆分”成若干个独立的小组,然后对每个小组独立地“应用”一个函数(比如求和、求平均、自定义函数),最后将这些独立计算的结果“合并”成一个新的DataFrame或Series。这个过程,在我看来,是数据分析中非常优雅且高效的模式。

Python怎样实现数据聚合?groupby方法

groupby在处理大规模数据集时有哪些性能考量?

当我们面对GB甚至TB级别的数据时,groupby的性能就不仅仅是“能用”的问题了,而是“能否高效地用”的问题。我个人在处理大表时,确实遇到过一些性能瓶颈,总结下来有几点值得注意。

首先,内存消耗是个大头。groupby在内部需要创建一些中间对象来存储分组信息和临时计算结果。如果分组的键(比如用户ID、时间戳)非常多且唯一值数量巨大,或者每个组的数据量都很大,内存占用会迅速飙升。有时候,一个看似简单的groupby操作,可能导致内存溢出。

其次,聚合函数的选择也影响性能。内置的聚合函数(如sum(), mean(), count(), min(), max())通常是用C语言实现的,效率极高。但如果你频繁使用apply()方法配合Python自定义函数进行聚合,性能可能会大幅下降。因为apply()在每个组上都会调用Python解释器,这会带来额外的开销。如果可以,尽量用内置函数或NumPy函数。

再者,分组键的数据类型也很关键。如果你的分组键是字符串,尤其是长字符串,那么比较和哈希操作会相对较慢。将字符串列转换为category类型(分类类型)可以显著提升groupby的性能和减少内存占用,因为category类型在内部存储的是整数编码,而不是实际的字符串。这在处理像省份、城市、产品类别这类有限且重复性高的字符串时尤其有效。

# 示例:将字符串列转换为category类型
df_large = pd.DataFrame({
    '城市': np.random.choice(['北京', '上海', '广州', '深圳', '杭州', '成都'], 1000000),
    '销售额': np.random.rand(1000000) * 1000
})

# 转换前
print("转换前数据类型:", df_large['城市'].dtype)
%timeit df_large.groupby('城市')['销售额'].sum()

# 转换后
df_large['城市'] = df_large['城市'].astype('category')
print("转换后数据类型:", df_large['城市'].dtype)
%timeit df_large.groupby('城市')['销售额'].sum()

(注:上述%timeit需要在Jupyter或IPython环境中运行才能看到效果,这里仅作示例说明)

此外,如果你的数据量真的非常庞大,超出了单机内存限制,那么你可能需要考虑Dask、Spark等分布式计算框架,它们提供了与pandas类似的API,但能在集群上并行处理数据。不过,这已经超出了pandas本身的范畴了。

除了基础聚合,groupby还能实现哪些高级数据变换?

groupby的魅力远不止于简单的summean。它还有几个非常强大的伴侣方法,能让你在分组的基础上进行更复杂的数据变换和筛选,它们是transform()filter()apply()

transform()方法非常独特。它在分组后应用一个函数,然后将结果“广播”回原始DataFrame的形状。这意味着输出的Series或DataFrame的索引和原始数据是完全对齐的。这对于填充缺失值、标准化数据或计算组内排名等场景非常有用。

比如,我想填充每个地区的平均销售额到该地区缺失的销售额记录中,或者我想计算每个销售额在其所属地区的Z-score(标准化分数),transform就是不二之选。

# 示例:使用transform进行组内标准化(Z-score)
df_transform = pd.DataFrame({
    '地区': ['华东', '华南', '华东', '华北', '华南', '华东', '华北', '华南'],
    '销售额': [100, 150, 120, 80, 200, 90, 110, 130]
})

# 计算每个地区销售额的Z-score
df_transform['销售额_Zscore'] = df_transform.groupby('地区')['销售额'].transform(lambda x: (x - x.mean()) / x.std(ddof=1))
print("使用transform进行组内标准化:")
print(df_transform)
print("-" * 30)

filter()方法则用于筛选整个组。它接收一个函数,这个函数对每个组返回一个布尔值(True或False)。如果返回True,则保留该组的所有行;如果返回False,则丢弃该组的所有行。这对于只分析满足特定条件的组非常有用。

例如,我只想看那些销售额总和超过某个阈值的地区的数据,或者只保留那些至少有N个产品的地区。

Cliclic AI
Cliclic AI

Cliclic商品背景图编辑器是一款功能强大的AI工具,帮助用户快速生成具有吸引力的商品图背景。

下载
# 示例:使用filter筛选销售额总和大于300的地区
print("使用filter筛选销售额总和大于300的地区:")
filtered_df = df.groupby('地区').filter(lambda x: x['销售额'].sum() > 300)
print(filtered_df)
print("-" * 30)

注意看,filter返回的是原始DataFrame的子集,保留了符合条件的整个组的数据。

最后是apply(),它是groupby家族中最灵活的。它允许你将任何函数应用到每个分组上,这个函数可以返回一个标量、一个Series、一个DataFrame,甚至是一个列表。apply()的强大之处在于它的通用性,你可以用它来完成transformfilter无法直接实现,或者需要更复杂逻辑的操作。

比如,我想对每个地区的数据进行某种模型预测,或者计算每个地区的某个复杂指标,apply()就能派上用场。但正如前面提到的,它的性能开销通常比内置函数或transform大。

# 示例:使用apply计算每个地区销售额的“销售额/销量”平均值(假设这是个复杂指标)
# 注意:这里为了演示apply的灵活性,实际操作中可能直接计算再聚合
def custom_metric(group):
    # 假设我们想计算每个组的销售额和销量的比率的平均值
    if group['销量'].sum() == 0:
        return 0
    return (group['销售额'] / group['销量']).mean()

print("使用apply进行自定义复杂指标计算:")
custom_agg = df.groupby('地区').apply(custom_metric)
print(custom_agg)
print("-" * 30)

理解这三者的区别和适用场景,能让你在数据处理时更加游刃有余。简单来说,需要广播结果回原始形状用transform,需要根据组的特性筛选组用filter,而需要对每个组执行任意复杂逻辑则用apply

groupby与SQL中的GROUP BY有什么异同?如何进行等效操作?

作为一名数据分析师,我经常在Python和SQL之间切换,自然会思考它们在数据聚合上的异同。pandasgroupby和SQL的GROUP BY在核心理念上是高度一致的,都是基于“分而治之”的思想,将数据按指定键分组,然后对每个组执行聚合操作。但它们在语法和某些高级功能上还是有些区别。

共同点:

  • 核心功能: 都是用来进行数据聚合,比如计算总和、平均值、计数、最大值、最小值等。
  • 分组键: 都支持按一个或多个列进行分组。
  • 聚合函数: 都提供了一系列内置的聚合函数。

不同点:

  1. 输出形式:

    • SQL的GROUP BY通常要求SELECT语句中除了聚合列,其他列必须是分组键。结果是一个新的、行数减少的表。
    • pandasgroupby默认会将分组键作为结果DataFrame的索引(或多级索引)。它对非聚合列的处理更灵活,你可以选择性地聚合它们,或者在后续操作中通过reset_index()将其变回普通列。
  2. 高级功能:

    • pandasgroupby提供了transform()filter()这两个SQL中没有直接对应但功能强大的方法。transform()可以实现类似SQL窗口函数(Window Functions)的部分功能,比如计算组内排名或填充组内平均值。filter()则可以实现SQL的HAVING子句功能,但更灵活。
    • SQL有更丰富的窗口函数,例如ROW_NUMBER(), LAG(), LEAD()等,这些在pandas中通常需要结合groupby().transform()或更复杂的逻辑来实现。
  3. 自定义函数:

    • pandasapply()方法允许你将任意Python函数应用到每个组,这在SQL中实现自定义聚合函数通常需要编写用户定义函数(UDF),相对复杂一些。

等效操作:

我们来看几个常见的SQL GROUP BY操作如何用pandas实现。

场景1:计算每个地区总销售额

  • SQL:
    SELECT 地区, SUM(销售额) AS 总销售额
    FROM 销售表
    GROUP BY 地区;
  • Pandas:
    region_sales_pd = df.groupby('地区')['销售额'].sum().reset_index()
    print("Pandas等效SQL查询1:")
    print(region_sales_pd)
    print("-" * 30)

场景2:计算每个地区和产品的平均销售额和总销量

  • SQL:
    SELECT 地区, 产品, AVG(销售额) AS 平均销售额, SUM(销量) AS 总销量
    FROM 销售表
    GROUP BY 地区, 产品;
  • Pandas:
    multi_agg_pd = df.groupby(['地区', '产品']).agg(
        平均销售额=('销售额', 'mean'),
        总销量=('销量', 'sum')
    ).reset_index()
    print("Pandas等效SQL查询2:")
    print(multi_agg_pd)
    print("-" * 30)

场景3:筛选出总销售额超过200的地区

  • SQL (使用HAVING):
    SELECT 地区, SUM(销售额) AS 总销售额
    FROM 销售表
    GROUP BY 地区
    HAVING SUM(销售额) > 200;
  • Pandas (使用filter):
    filtered_region_pd = df.groupby('地区').filter(lambda x: x['销售额'].sum() > 200)
    # 如果只想看聚合结果,可以先filter再聚合
    # filtered_region_agg_pd = filtered_region_pd.groupby('地区')['销售额'].sum().reset_index()
    print("Pandas等效SQL查询3 (使用filter):")
    print(filtered_region_pd) # filter返回原始数据
    print("-" * 30)

可以看到,pandasgroupby在很多情况下提供了与SQL GROUP BY相似甚至更灵活的功能。理解它们之间的映射关系,能帮助我们更流畅地在不同工具间切换,并选择最适合当前任务的实现方式。在我看来,掌握groupby的各种高级用法,是真正发挥pandas数据处理能力的关键一步。

热门AI工具

更多
DeepSeek
DeepSeek

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

豆包大模型
豆包大模型

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

WorkBuddy
WorkBuddy

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

腾讯元宝
腾讯元宝

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

文心一言
文心一言

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

讯飞写作
讯飞写作

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

即梦AI
即梦AI

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

ChatGPT
ChatGPT

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

相关专题

更多
C语言变量命名
C语言变量命名

c语言变量名规则是:1、变量名以英文字母开头;2、变量名中的字母是区分大小写的;3、变量名不能是关键字;4、变量名中不能包含空格、标点符号和类型说明符。php中文网还提供c语言变量的相关下载、相关课程等内容,供大家免费下载使用。

410

2023.06.20

c语言入门自学零基础
c语言入门自学零基础

C语言是当代人学习及生活中的必备基础知识,应用十分广泛,本专题为大家c语言入门自学零基础的相关文章,以及相关课程,感兴趣的朋友千万不要错过了。

638

2023.07.25

c语言运算符的优先级顺序
c语言运算符的优先级顺序

c语言运算符的优先级顺序是括号运算符 > 一元运算符 > 算术运算符 > 移位运算符 > 关系运算符 > 位运算符 > 逻辑运算符 > 赋值运算符 > 逗号运算符。本专题为大家提供c语言运算符相关的各种文章、以及下载和课程。

362

2023.08.02

c语言数据结构
c语言数据结构

数据结构是指将数据按照一定的方式组织和存储的方法。它是计算机科学中的重要概念,用来描述和解决实际问题中的数据组织和处理问题。数据结构可以分为线性结构和非线性结构。线性结构包括数组、链表、堆栈和队列等,而非线性结构包括树和图等。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

263

2023.08.09

c语言random函数用法
c语言random函数用法

c语言random函数用法:1、random.random,随机生成(0,1)之间的浮点数;2、random.randint,随机生成在范围之内的整数,两个参数分别表示上限和下限;3、random.randrange,在指定范围内,按指定基数递增的集合中获得一个随机数;4、random.choice,从序列中随机抽选一个数;5、random.shuffle,随机排序。

631

2023.09.05

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

562

2023.09.20

c语言get函数的用法
c语言get函数的用法

get函数是一个用于从输入流中获取字符的函数。可以从键盘、文件或其他输入设备中读取字符,并将其存储在指定的变量中。本文介绍了get函数的用法以及一些相关的注意事项。希望这篇文章能够帮助你更好地理解和使用get函数 。

671

2023.09.20

c数组初始化的方法
c数组初始化的方法

c语言数组初始化的方法有直接赋值法、不完全初始化法、省略数组长度法和二维数组初始化法。详细介绍:1、直接赋值法,这种方法可以直接将数组的值进行初始化;2、不完全初始化法,。这种方法可以在一定程度上节省内存空间;3、省略数组长度法,这种方法可以让编译器自动计算数组的长度;4、二维数组初始化法等等。

618

2023.09.22

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

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

26

2026.03.13

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新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号