笔记:《利用Python进行数据分析》之数据聚合

news2024/9/19 10:41:56

观前提示:这节内容不多,但难度较大,尤其是要能熟练运用时很不容易的

数据聚合

聚合指的是任何能够从数组产生标量值的数据转换过程。之前的例子已经用过一些,比如mean、count、min以及sum等。你可能想知道在GroupBy对象上调用mean()时究竟发生了什么。许多常见的聚合运算(如表10-1所示)都有进行优化。然而,除了这些方法,你还可以使用其它的。

表10-1 经过优化的groupby方法

你可以使用自己发明的聚合运算,还可以调用分组对象上已经定义好的任何方法。例如,quantile可以计算Series或DataFrame列的样本分位数。

虽然quantile并没有明确地实现于GroupBy,但它是一个Series方法,所以这里是能用的。实际上,GroupBy会高效地对Series进行切片,然后对各片调用piece.quantile(0.9),最后将这些结果组装成最终结果:

In [51]: df
Out[51]: 
      data1     data2 key1 key2
0 -0.204708  1.393406    a  one
1  0.478943  0.092908    a  two
2 -0.519439  0.281746    b  one
3 -0.555730  0.769023    b  two
4  1.965781  1.246435    a  one
In [52]: grouped = df.groupby('key1')
In [53]: grouped['data1'].quantile(0.9)
Out[53]: 
key1
a    1.668413
b   -0.523068
Name: data1, dtype: float64

如果要使用你自己的聚合函数,只需将其传入aggregate或agg方法即可:

In [54]: def peak_to_peak(arr):
   ....:     return arr.max() - arr.min()
In [55]: grouped.agg(peak_to_peak)
Out[55]: 
         data1     data2
key1                    
a     2.170488  1.300498
b     0.036292  0.487276

你可能注意到注意,有些方法(如describe)也是可以用在这里的,即使严格来讲,它们并非聚合运算:

In [56]: grouped.describe()
Out[56]: 
     data1                                                              \
     count      mean       std       min       25%       50%       75%   
key1                                                                     
a      3.0  0.746672  1.109736 -0.204708  0.137118  0.478943  1.222362   
b      2.0 -0.537585  0.025662 -0.555730 -0.546657 -0.537585 -0.528512   
               data2                                                    \
max count      mean       std       min       25%       50%   
key1                                                                     
a     1.965781   3.0  0.910916  0.712217  0.092908  0.669671  1.246435   
b    -0.519439   2.0  0.525384  0.344556  0.281746  0.403565  0.525384   
           75%       max  
key1                      
a     1.319920  1.393406  
b     0.647203  0.769023

自定义聚合函数要比表10-1中那些经过优化的函数慢得多。这是因为在构造中间分组数据块时存在非常大的开销(函数调用、数据重排等)。

面向列的多函数应用

回到前面小费的例子。使用read_csv导入数据之后,我们添加了一个小费百分比的列tip_pct:

In [57]: tips = pd.read_csv('examples/tips.csv')
# Add tip percentage of total bill
In [58]: tips['tip_pct'] = tips['tip'] / tips['total_bill']
In [59]: tips[:6]
Out[59]: 
   total_bill   tip smoker  day    time  size   tip_pct
0       16.99  1.01     No  Sun  Dinner     2  0.059447
1       10.34  1.66     No  Sun  Dinner     3  0.160542
2       21.01  3.50     No  Sun  Dinner     3  0.166587
3       23.68  3.31     No  Sun  Dinner     2  0.139780
4       24.59  3.61     No  Sun  Dinner     4  0.146808
5       25.29  4.71     No  Sun  Dinner     4  0.186240

你已经看到,对Series或DataFrame列的聚合运算其实就是使用aggregate(使用自定义函数)或调用诸如mean、std之类的方法。然而,你可能希望对不同的列使用不同的聚合函数,或一次应用多个函数。其实这也好办,我将通过一些示例来进行讲解。首先,我根据天和smoker对tips进行分组:

In [60]: grouped = tips.groupby(['day', 'smoker'])

In [61]: grouped_pct = grouped['tip_pct']
In [62]: grouped_pct.agg('mean')
Out[62]: 
day   smoker
Fri   No        0.151650
      Yes       0.174783
Sat   No        0.158048
      Yes       0.147906
Sun   No        0.160113
      Yes       0.187250
Thur  No        0.160298
      Yes       0.163863
Name: tip_pct, dtype: float64

如果传入一组函数或函数名,得到的DataFrame的列就会以相应的函数命名:

In [63]: grouped_pct.agg(['mean', 'std', peak_to_peak])
Out[63]: 
                 mean       std  peak_to_peak
day  smoker                                  
Fri  No      0.151650  0.028123      0.067349
     Yes     0.174783  0.051293      0.159925
Sat  No      0.158048  0.039767      0.235193
     Yes     0.147906  0.061375      0.290095
Sun  No      0.160113  0.042347      0.193226
     Yes     0.187250  0.154134      0.644685
Thur No      0.160298  0.038774      0.193350
     Yes     0.163863  0.039389      0.151240

这里,我们传递了一组聚合函数进行聚合,独立对数据分组进行评估。

你并非一定要接受GroupBy自动给出的那些列名,特别是lambda函数,它们的名称是’‘,这样的辨识度就很低了(通过函数的name属性看看就知道了)。因此,如果传入的是一个由(name,function)元组组成的列表,则各元组的第一个元素就会被用作DataFrame的列名(可以将这种二元元组列表看做一个有序映射):

In [64]: grouped_pct.agg([('foo', 'mean'), ('bar', np.std)])
Out[64]: 
                  foo       bar
day  smoker                    
Fri  No      0.151650  0.028123
     Yes     0.174783  0.051293
Sat  No      0.158048  0.039767
     Yes     0.147906  0.061375
Sun  No      0.160113  0.042347
     Yes     0.187250  0.154134
Thur No      0.160298  0.038774
     Yes     0.163863  0.039389

对于DataFrame,你还有更多选择,你可以定义一组应用于全部列的一组函数,或不同的列应用不同的函数。假设我们想要对tip_pct和total_bill列计算三个统计信息:

In [65]: functions = ['count', 'mean', 'max']
In [66]: result = grouped['tip_pct', 'total_bill'].agg(functions)
In [67]: result
Out[67]: 
            tip_pct                     total_bill                  
              count      mean       max      count       mean    max
day  smoker                                                         
Fri  No           4  0.151650  0.187735          4  18.420000  22.75
     Yes         15  0.174783  0.263480         15  16.813333  40.17
Sat  No          45  0.158048  0.291990         45  19.661778  48.33
     Yes         42  0.147906  0.325733         42  21.276667  50.81
Sun  No          57  0.160113  0.252672         57  20.506667  48.17
     Yes         19  0.187250  0.710345         19  24.120000  45.35
Thur No          45  0.160298  0.266312         45  17.113111  41.19
     Yes         17  0.163863  0.241255         17  19.190588  43.11

如你所见,结果DataFrame拥有层次化的列,这相当于分别对各列进行聚合,然后用concat将结果组装到一起,使用列名用作keys参数:

In [68]: result['tip_pct']
Out[68]: 
             count      mean       max
day  smoker                           
Fri  No          4  0.151650  0.187735
     Yes        15  0.174783  0.263480
Sat  No         45  0.158048  0.291990
     Yes        42  0.147906  0.325733
Sun  No         57  0.160113  0.252672
     Yes        19  0.187250  0.710345
Thur No         45  0.160298  0.266312
     Yes        17  0.163863  0.241255

跟前面一样,这里也可以传入带有自定义名称的一组元组:

In [69]: ftuples = [('Durchschnitt', 'mean'),('Abweichung', np.var)]
In [70]: grouped['tip_pct', 'total_bill'].agg(ftuples)
Out[70]: 
                 tip_pct              total_bill            
            Durchschnitt Abweichung Durchschnitt  Abweichung
day  smoker                                                 
Fri  No         0.151650   0.000791    18.420000   25.596333
     Yes        0.174783   0.002631    16.813333   82.562438
Sat  No         0.158048   0.001581    19.661778   79.908965
     Yes        0.147906   0.003767    21.276667  101.387535
Sun  No         0.160113   0.001793    20.506667   66.099980
     Yes        0.187250   0.023757    24.120000  109.046044
Thur No         0.160298   0.001503    17.113111   59.625081
     Yes        0.163863   0.001551    19.190588   69.808518

现在,假设你想要对一个列或不同的列应用不同的函数。具体的办法是向agg传入一个从列名映射到函数的字典:

In [71]: grouped.agg({'tip' : np.max, 'size' : 'sum'})
Out[71]: 
               tip  size
day  smoker             
Fri  No       3.50     9
     Yes      4.73    31
Sat  No       9.00   115
     Yes     10.00   104
Sun  No       6.00   167
     Yes      6.50    49
Thur No       6.70   112
     Yes      5.00    40
In [72]: grouped.agg({'tip_pct' : ['min', 'max', 'mean', 'std'],
   ....:              'size' : 'sum'})
Out[72]: 
              tip_pct                               size
                  min       max      mean       std  sum
day  smoker                                             
Fri  No      0.120385  0.187735  0.151650  0.028123    9
     Yes     0.103555  0.263480  0.174783  0.051293   31
Sat  No      0.056797  0.291990  0.158048  0.039767  115
     Yes     0.035638  0.325733  0.147906  0.061375  104
Sun  No      0.059447  0.252672  0.160113  0.042347  167
     Yes     0.065660  0.710345  0.187250  0.154134   49
Thur No      0.072961  0.266312  0.160298  0.038774  112
     Yes     0.090014  0.241255  0.163863  0.039389   40

只有将多个函数应用到至少一列时,DataFrame才会拥有层次化的列。

以“没有行索引”的形式返回聚合数据

到目前为止,所有示例中的聚合数据都有由唯一的分组键组成的索引(可能还是层次化的)。由于并不总是需要如此,所以你可以向groupby传入as_index=False以禁用该功能:

In [73]: tips.groupby(['day', 'smoker'], as_index=False).mean()
Out[73]: 
    day smoker  total_bill       tip      size   tip_pct
0   Fri     No   18.420000  2.812500  2.250000  0.151650
1   Fri    Yes   16.813333  2.714000  2.066667  0.174783
2   Sat     No   19.661778  3.102889  2.555556  0.158048
3   Sat    Yes   21.276667  2.875476  2.476190  0.147906
4   Sun     No   20.506667  3.167895  2.929825  0.160113
5   Sun    Yes   24.120000  3.516842  2.578947  0.187250
6  Thur     No   17.113111  2.673778  2.488889  0.160298
7  Thur    Yes   19.190588  3.030000  2.352941  0.163863

小结

数据聚合是数据分析中的一个重要概念,它涉及将一组数据转换成单个数值的过程。在Python的Pandas库中,数据聚合通常通过`GroupBy`对象来实现,该对象允许对数据进行分组,并对每个分组应用聚合函数。

以下是一些关键点的总结:

1. 常见聚合函数:如`mean`、`count`、`min`、`max`和`sum`等,它们可以直接应用于`GroupBy`对象。

2. 自定义聚合函数:用户可以定义自己的聚合函数,如`peak_to_peak`,然后通过`aggregate`或`agg`方法应用到`GroupBy`对象上。

3. 分位数计算:虽然`quantile`不是直接实现在`GroupBy`上,但它是`Series`的方法,可以通过`GroupBy`高效地对数据切片并应用。

4. 多函数聚合:可以对不同的列使用不同的聚合函数,或者一次应用多个函数。例如,使用`agg`方法传入一个函数列表或字典,对不同的列进行不同的聚合操作。

5. 列名自定义:在聚合时,可以通过传递`(name, function)`元组列表来自定义结果DataFrame的列名。

6. DataFrame的聚合:可以对DataFrame的不同列应用不同的函数,或者对所有列应用同一组函数。

7. 无索引的聚合结果:通过设置`as_index=False`,可以返回没有行索引的聚合数据,使得结果更易于理解和操作。

8. 描述性统计:方法如`describe`可以提供数据的描述性统计信息,虽然它们不是聚合运算,但可以用于`GroupBy`对象。

通过这些方法,Pandas提供了强大的工具来对数据进行分组和聚合,使得数据分析更加灵活和高效。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2095892.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

网络原理 - 初识

文章目录 局域网(LAN)广域网(WAN)网络设备IP地址格式 端口号格式 认识网络协议协议分层 OSI七层模型(只是理论,没有实际运用)TCP/IP五层(或四层)模型网络设备所在分层 封装和分用 计算机之间通过网络来传输数据,也称为网络通信。 根据网络互连…

AI问答:.NET核心组成概要、程序运行步骤和查询SDK版本的方法

.NET三大组成 ①Runtime (运行时): CLR:公共语言运行时,执行程序、内存管理、垃圾回收(GC)、安全性检查、异常处理,是跨平台的关键要素。 JIT:实时编译器,将中间语言…

JDBC与数据库之间的操作(增删改查、获取主键、业务逻辑分离、属性文件配置)

参考视频哔哩哔哩 1、Service和Servicelmpl的概念 java中service和servicelmpl是常见的代码组织方式 Service是指业务逻辑的接口,定义了系统对外提供的功能。Servicelmpl是Service接口的具体实现,实现了具体的业务逻辑。 Service和Servicelmpl的好处…

Android自定义View实现不同朝向字体变色

实现效果: 1.一个文字两种颜色 2.实现不同朝向 3.结合ViewPager 思路:TextView可行?系统提供的只能够显示一种颜色,需要自定义View extends TextView:onMeasure()不需要实现 textColor颜色,textSize字体大小…

OpenAI Whisper API (InvalidRequestError)

题意: OpenAI Whisper API(无效请求错误) 问题背景: Im trying to use OpenAI Whisper API to transcribe my audio files. When I run it by opening my local audio files from disk, it worked perfectly. Now Im developing a FastAPI e…

学习WebGl基础知识(二)

学习目标&#xff1a; 掌握WebGl基础知识 学习内容&#xff1a; 创建一个Webgl程序 创建三维上下文对象创建顶点着色器和片元着色器创建和编译顶点着色器和片元着色器创建着色器程序对象绘制图元 创建一个Webgl程序 1.第一步获取画布&#xff0c;创建三维上下文对象 <ca…

一些硬件知识(十七)

电源芯片选型&#xff1a; 1.考虑拓扑结构 2.考虑功率&#xff0c;从而决定自行搭建电路还是选择芯片 3.对于低功耗产品&#xff0c;静态电流是非常重要的因素&#xff0c;一定重要考虑&#xff1a; 同步buck省去了续流二极管&#xff0c;效率比异步的高。 如果真的比耐压值…

ESP32小车:1.硬件模块与连接

一、硬件模块 总的元器件清单:亚克力板(三轮),两个普通减速电机,一个开关模块,一个 首先,需要一块亚克力单层底板,推荐随便在淘宝上买一块2WD亚克力单层板,比如: 最好亚克力板自带电机,买一套也不过15块。如果没有需另外购买两个普通TT直流减速电机和轮子。…

基于yolov8的102种昆虫检测系统python源码+onnx模型+评估指标曲线+精美GUI界面

【算法介绍】 基于YOLOv8的102种昆虫检测系统是一款高效、准确的昆虫识别工具&#xff0c;它利用YOLOv8这一先进的目标检测算法&#xff0c;实现了对102种不同昆虫的实时检测与识别。该系统在农业、生态研究、生物多样性保护等多个领域具有广泛的应用价值。 YOLOv8算法以其高…

HTML沙漏爱心

目录 写在前面 完整代码 下载代码 代码分析 系列文章 写在最后 写在前面 教你用HTML语言实现炫酷的沙漏爱心,该代码不仅可以用电脑运行,手机、平板也可以直接运行哦。 完整代码 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><…

【Linux】:文件IO

目录 1.C文件接口 1.1 当前路径是什么&#xff1f; 1.2 "w"和"a"​编辑 2.系统文件I/O 2.1 "比特宏"标识符的实现: 2.2 open 1.系统默认创建文件的权限只写 2.设置新建文件的权限 3. 覆盖写/清空写/追加写 3.访问文件的本质 3.1 文件…

茴香豆Web实践

茴香豆 是由书生浦语团队开发的一款开源、专门针对国内企业级使用场景设计并优化的知识问答工具。 茴香豆特点&#xff1a; 三阶段 Pipeline &#xff08;前处理、拒答、响应&#xff09;&#xff0c;提高相应准确率和安全性 打通微信和飞书群聊天&#xff0c;适合国内知识问…

提高工作效益方法(一)

目录 如何提高工作效率? 如何提高工作效率?&#xff08;每日工作安排&#xff09; 怎么在职场做好时间管理&#xff1f; 如何提高工作效率? 提高工作效率的关键在于采用一系列策略和方法&#xff0c;以确保工作能够高效、有序地进行。通过这些方法&#xff0c;可以有效地提…

【whisper】使用whisper实现语音转文字

whisper需要ffmpeg支持 官网下载ffmpeg https://www.gyan.dev/ffmpeg/builds/下载完毕后解压放到合适的位置 添加环境变量 在cmd中输入以下 ffmpeg -version出现下面结果代表成功 安装whisper pip install openai-whisper在vscode中运行 测试代码 import whisperif __n…

【c++】cout打印char * 或者char[]的细节详解

目录 char* 类型 1.打印指向的字符串 2.打印指针指向的地址 问题描述 解决方法 char型数组 1. 想要输出字符串 2. 想输出字符数组的地址 printf 和cout 的对比 1.打印首字符 2.打印字符串 3.打印字符串首地址 &#x1f497;感谢阅读&#xff01;&#x1f497; char*…

新火种AI|减脂增肌没捷径?对不起,那是AI 出现以前的事情了...

作者&#xff1a;小岩 编辑&#xff1a;彩云 对于很多人来说&#xff0c;“拥有完美的身材”是人生的重要目标之一&#xff0c;练出好身材的人也会以此为傲&#xff0c;会把自己的好身材po到社交媒体上。换个角度来说&#xff0c;为了让自己社交媒体上的形象足够完美&#xf…

Axure RP下载+详细安装步骤资源百度云盘分享

众所周知&#xff0c;Axure全称“axure rp”&#xff0c;是一款专业的快速原型设计工具。 它能帮助网站需求设计者&#xff0c;快捷而简便的创建基于网站构架图的带注释页面示意图、操作流程图、以及交互设计&#xff0c;并可自动生成用于演示的网页文件和规格文件&#xff0c…

小琳python课堂:Python核心概念 类和对象

大家好&#xff0c;这里是小琳python课堂&#xff01;今天我们来聊聊Python中的类&#xff08;Class&#xff09;和对象&#xff08;Object&#xff09;&#xff0c;这是面向对象编程&#xff08;OOP&#xff09;的核心概念哦&#xff01;&#x1f31f; 面向对象编程就像是用“…

基于 INFINI Pizza 为 Hugo 静态站点添加搜索功能

INFINI Pizza 是 INFINI Labs 即将发布的一个基于 Rust 编写的搜索引擎&#xff08;即将完全开源&#xff09;&#xff0c;目前已经完成基本的搜索能力&#xff0c;并且基于 INFINI Pizza 的核心引擎&#xff0c;提供了一个 WASM 版本的超轻量级内核&#xff0c;可以很方便的嵌…

MicroNet关键代码解读(Micro-block与Dynamic Shift-Max的实现代码)

论文地址&#xff1a;https://arxiv.org/pdf/2011.12289 中文翻译&#xff1a;https://hpg123.blog.csdn.net/article/details/141772832?spm1001.2014.3001.5502 发表时间&#xff1a;2022 项目地址&#xff1a;https://github.com/liyunsheng13/micronet 在MicroNet论文中提…