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

pandas教程:Data Aggregation 数据聚合

文章目录

  • 10.2 Data Aggregation(数据聚合)
  • 1 Column-Wise and Multiple Function Application(列对列和多函数应用)
  • 2 Returning Aggregated Data Without Row Indexes(不使用行索引返回聚合数据)

10.2 Data Aggregation(数据聚合)

聚合(Aggregation)指的是一些数据转化(data transformation),这些数据转化能从数组中产生标量(scalar values)。下面的例子就是一些聚合方法,包括mean, count, min and sum。我们可能会好奇,在一个GroupBy对象上调用mean()的时候,究竟发生了什么。一些常见的聚合,比如下表,实现方法上都已经被优化过了。当然,我们可以使用的聚合方法不止这些:

我们可以使用自己设计的聚合方法,而且可以调用分组后对象上的任意方法。例如,我们可以调用quantile来计算SeriesDataFrame中列的样本的百分数。

尽管quantile并不是专门为GroupBy对象设计的方法,这是一个Series方法,但仍可以被GroupBy对象使用。GroupBy会对Series进行切片(slice up),并对于切片后的每一部分调用piece.quantile(0.9),然后把每部分的结果整合到一起

import numpy as np
import pandas as pd
df = pd.DataFrame({'key1' : ['a', 'a', 'b', 'b', 'a'],'key2' : ['one', 'two', 'one', 'two', 'one'], 'data1' : np.random.randn(5), 'data2' : np.random.randn(5)})
df
data1data2key1key2
01.7077380.186729aone
11.0698311.305796atwo
2-2.291339-1.609071bone
31.348090-0.294999btwo
40.3411760.429461aone
grouped = df.groupby('key1')
for key, group in grouped:print(key)print(group)
adata1     data2 key1 key2
0  1.707738  0.186729    a  one
1  1.069831  1.305796    a  two
4  0.341176  0.429461    a  one
bdata1     data2 key1 key2
2 -2.291339 -1.609071    b  one
3  1.348090 -0.294999    b  two
grouped['data1'].quantile(0.9)
key1
a    1.580157
b    0.984147
Name: data1, dtype: float64

如果想用自己设计的聚合函数,把用于聚合数组的函数传入到aggregateagg方法即可:

def peak_to_peak(arr):return arr.max() - arr.min()
grouped.agg(peak_to_peak)
data1data2
key1
a1.3665631.119067
b3.6394301.314072

我们发现很多方法,比如describe,也能正常使用,尽管严格的来说,这并不是聚合:

grouped.describe()
data1data2
key1
acount3.0000003.000000
mean1.0395820.640662
std0.6837830.588670
min0.3411760.186729
25%0.7055030.308095
50%1.0698310.429461
75%1.3887850.867629
max1.7077381.305796
bcount2.0000002.000000
mean-0.471624-0.952035
std2.5734650.929189
min-2.291339-1.609071
25%-1.381482-1.280553
50%-0.471624-0.952035
75%0.438233-0.623517
max1.348090-0.294999

细节的部分在10.3会进行更多解释。

注意:自定义的函数会比上面表中的函数慢一些,上面的函数时优化过的,而自定义的函数会有一些额外的计算,所以慢一些。

1 Column-Wise and Multiple Function Application(列对列和多函数应用)

让我们回到tipping数据集。加载数据及后,我们添加一列用于描述小费的百分比:

tips = pd.read_csv('../examples/tips.csv')
# Add tip percentage of total bill
tips['tip_pct'] = tips['tip'] / tips['total_bill']
tips[:6]
total_billtipsmokerdaytimesizetip_pct
016.991.01NoSunDinner20.059447
110.341.66NoSunDinner30.160542
221.013.50NoSunDinner30.166587
323.683.31NoSunDinner20.139780
424.593.61NoSunDinner40.146808
525.294.71NoSunDinner40.186240

我们可以看到,对seriesDataFrame进行聚合,其实就是通过aggregate使用合适的函数,或者调用一些像meanstd这样的方法。然而,我们可能想要在列上使用不同的函数进行聚合,又或者想要一次执行多个函数。幸运的是,这是可能的,下面将通过一些例子来说明。首先,对于tips数据集,先用daysmoker进行分组:

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

对于像是上面表格10-1中的一些描述性统计,我们可以直接传入函数的名字,即字符串:

grouped_pct = grouped['tip_pct']
for name, group in grouped_pct:print(name)print(group[:2], '\n')
('Fri', 'No')
91    0.155625
94    0.142857
Name: tip_pct, dtype: float64 ('Fri', 'Yes')
90    0.103555
92    0.173913
Name: tip_pct, dtype: float64 ('Sat', 'No')
19    0.162228
20    0.227679
Name: tip_pct, dtype: float64 ('Sat', 'Yes')
56    0.078927
58    0.156584
Name: tip_pct, dtype: float64 ('Sun', 'No')
0    0.059447
1    0.160542
Name: tip_pct, dtype: float64 ('Sun', 'Yes')
164    0.171331
172    0.710345
Name: tip_pct, dtype: float64 ('Thur', 'No')
77    0.147059
78    0.131810
Name: tip_pct, dtype: float64 ('Thur', 'Yes')
80    0.154321
83    0.152999
Name: tip_pct, dtype: float64 
grouped_pct.agg('mean')
day   smoker
Fri   No        0.151650Yes       0.174783
Sat   No        0.158048Yes       0.147906
Sun   No        0.160113Yes       0.187250
Thur  No        0.160298Yes       0.163863
Name: tip_pct, dtype: float64

如果我们把函数或函数的名字作为一个list传入,我们会得到一个DataFrame,每列的名字就是函数的名字:

# def peak_to_peak(arr):
#     return arr.max() - arr.min()
grouped_pct.agg(['mean', 'std', peak_to_peak])
meanstdpeak_to_peak
daysmoker
FriNo0.1516500.0281230.067349
Yes0.1747830.0512930.159925
SatNo0.1580480.0397670.235193
Yes0.1479060.0613750.290095
SunNo0.1601130.0423470.193226
Yes0.1872500.1541340.644685
ThurNo0.1602980.0387740.193350
Yes0.1638630.0393890.151240

上面我们把多个聚合函数作为一个list传入给agg,这些函数会独立对每一个组进行计算。

上面结果的列名是自动给出的,当然,我们也可以更改这些列名。这种情况下,传入一个由tuple组成的list,每个tuple的格式是(name, function),每个元组的第一个元素会被用于作为DataFrame的列名(我们可以认为这个二元元组list是一个有序的映射):

grouped_pct.agg([('foo', 'mean'), ('bar', np.std)])
foobar
daysmoker
FriNo0.1516500.028123
Yes0.1747830.051293
SatNo0.1580480.039767
Yes0.1479060.061375
SunNo0.1601130.042347
Yes0.1872500.154134
ThurNo0.1602980.038774
Yes0.1638630.039389

如果是处理一个DataFrame,我们有更多的选择,我们可以用一个含有多个函数的list应用到所有的列上,也可以在不同的列上应用不同的函数。演示一下,假设我们想要在tip_pcttotal_bill这两列上,计算三个相同的统计指标:

functions = ['count', 'mean', 'max']
result = grouped['tip_pct', 'total_bill'].agg(functions)
result
tip_pcttotal_bill
countmeanmaxcountmeanmax
daysmoker
FriNo40.1516500.187735418.42000022.75
Yes150.1747830.2634801516.81333340.17
SatNo450.1580480.2919904519.66177848.33
Yes420.1479060.3257334221.27666750.81
SunNo570.1601130.2526725720.50666748.17
Yes190.1872500.7103451924.12000045.35
ThurNo450.1602980.2663124517.11311141.19
Yes170.1638630.2412551719.19058843.11

我们可以看到,结果中的DataFrame有多层级的列(hierarchical columns)。另外一种做法有相同的效果,即我们对于每一列单独进行聚合(aggregating each column separately),然后使用concat把结果都结合在一起,然后用列名作为keys参数:

result['tip_pct']
countmeanmax
daysmoker
FriNo40.1516500.187735
Yes150.1747830.263480
SatNo450.1580480.291990
Yes420.1479060.325733
SunNo570.1601130.252672
Yes190.1872500.710345
ThurNo450.1602980.266312
Yes170.1638630.241255

我们之前提到过,可以用元组组成的list来自己定义列名:

ftuples = [('Durchschnitt', 'mean'), ('Abweichung', np.var)]
grouped['tip_pct', 'total_bill'].agg(ftuples)
tip_pcttotal_bill
DurchschnittAbweichungDurchschnittAbweichung
daysmoker
FriNo0.1516500.00079118.42000025.596333
Yes0.1747830.00263116.81333382.562438
SatNo0.1580480.00158119.66177879.908965
Yes0.1479060.00376721.276667101.387535
SunNo0.1601130.00179320.50666766.099980
Yes0.1872500.02375724.120000109.046044
ThurNo0.1602980.00150317.11311159.625081
Yes0.1638630.00155119.19058869.808518

现在,假设我们想要把不同的函数用到一列或多列上。要做到这一点,给agg传递一个dict,这个dict需要包含映射关系,用来表示列名和函数之间的对应关系:

grouped.agg({'tip': np.max, 'size': 'sum'})
tipsize
daysmoker
FriNo3.509
Yes4.7331
SatNo9.00115
Yes10.00104
SunNo6.00167
Yes6.5049
ThurNo6.70112
Yes5.0040
grouped.agg({'tip_pct': ['min', 'max', 'mean', 'std'],'size': 'sum'})
tip_pctsize
minmaxmeanstdsum
daysmoker
FriNo0.1203850.1877350.1516500.0281239
Yes0.1035550.2634800.1747830.05129331
SatNo0.0567970.2919900.1580480.039767115
Yes0.0356380.3257330.1479060.061375104
SunNo0.0594470.2526720.1601130.042347167
Yes0.0656600.7103450.1872500.15413449
ThurNo0.0729610.2663120.1602980.038774112
Yes0.0900140.2412550.1638630.03938940

只有当多个函数用于至少一列的时候,DataFrame才会有多层级列(hierarchical columns

2 Returning Aggregated Data Without Row Indexes(不使用行索引返回聚合数据)

目前为止提到的所有例子,最后返回的聚合数据都是有索引的,而且这个索引默认是多层级索引,这个索引是由不同的组键的组合构成的(unique group key combinations)。因为我们并不是总需要返回这种索引,所以我们可以取消这种模式,在调用groupby的时候设定as_index=False即可:

tips.groupby(['day', 'smoker'], as_index=False).mean()
daysmokertotal_billtipsizetip_pct
0FriNo18.4200002.8125002.2500000.151650
1FriYes16.8133332.7140002.0666670.174783
2SatNo19.6617783.1028892.5555560.158048
3SatYes21.2766672.8754762.4761900.147906
4SunNo20.5066673.1678952.9298250.160113
5SunYes24.1200003.5168422.5789470.187250
6ThurNo17.1131112.6737782.4888890.160298
7ThurYes19.1905883.0300002.3529410.163863

当然,我们也可以在上面的结果上直接调用reset_index,这样的话就能得到之前那种多层级索引的结果。不过使用as_index=False方法可以避免一些不必要的计算。

http://www.lryc.cn/news/231406.html

相关文章:

  • 开启创造力之门:掌握Vue中Slot插槽的使用技巧与灵感
  • 【算法练习Day48】回文子串最长回文子序列
  • ubuntu下C++调用matplotlibcpp进行画图(超详细)
  • 芯科科技推出新的8位MCU系列产品,扩展其强大的MCU平台
  • Flink CDC
  • 数据结构-链表的简单操作代码实现3-LinkedList【Java版】
  • JTS: 24 MinimumDiameter 最小矩形
  • MacOS Ventura 13 优化配置(ARM架构新手向导)
  • 多区域OSPF配置
  • 【强化学习】day1 强化学习基础、马尔可夫决策过程、表格型方法
  • openwrt Docker不能联网
  • EtherCAT从站EEPROM组成信息详解(2):字8-15产品标识区
  • SpringBoot--中间件技术-4:整合Shiro,Shiro基于会话SessionManager实现分布式认证,附案例含源代码!
  • 【QT基础入门】QT中的容器类
  • IDEA没有Add Framework Support解决办法
  • 《009.SpringBoot之汽车租赁系统》
  • 第四代智能井盖传感器,万宾科技助力城市安全
  • ClickHouse 面试题
  • Python代码运行速度提升技巧!Python远比你想象中的快~
  • P6入门:项目初始化11-项目详情之计算Calculations
  • <MySQL> 查询数据进阶操作 -- 联合查询
  • centos 6.10 安装 svn1.14.2
  • Java实现俄罗斯方块
  • 【计算思维】少儿编程蓝桥杯青少组计算思维题考试真题及解析B
  • 第三章 栈和队列【24王道数据结构笔记】
  • 保姆级教程之SABO-VMD-CNN-SVM的分类诊断,特征可视化
  • 跳跃游戏(贪心思想)
  • 【JavaSE语法】类和对象(二)
  • 【SA8295P 源码分析 (三)】121 - MAX9295A 加串器芯片手册分析 及初始化参数分析
  • Maya 2024 for Mac(3D建模软件)