python中数据分组计算_python3数据聚合与分组运算(二)

本文详细介绍了在Python3中如何进行数据分组计算,包括使用Pandas库的GroupBy对象进行数据聚合、分组统计以及自定义聚合函数。通过实例展示了如何计算分位数、最大值、最小值等统计指标,并使用了如mean、count、std等多种聚合函数。还讲解了如何使用transform和apply方法进行分组级别的数据转换,以及如何填充缺失值和计算分组加权平均数。此外,文中提到了透视表(pivot_table)和交叉表(crosstab)的使用,展示了如何创建和操作这两种数据汇总工具。
摘要由CSDN通过智能技术生成

数据聚合

对于聚合,这里指的是任何能够从数组产生标量值的数据转换过程。之前的例子中已经用过一些,比如mean、count、min以及sum等。我们可能想知道在GroupBy对象上调用mean()时究竟发生了什么。许多常见的聚合运算(如下表所示)都有就地计算数据集统计信息的优化实现。然而,并不是只能使用这些方法。我们可以使用自己发明的聚合运算,还可以调用分组对象上已经定义好的任何方法。例如,quantile可以计算Series或DataFrame列的样本分位数:

In [1]: import pandas as pd

In [2]: from pandas import Series,DataFrame

In [3]: import numpy as np

In [4]: df=DataFrame({'key1':['a','a','b','b','a'],'key2':['one','two','one','t

...: wo','one'],'data1':np.random.randn(5),'data2':np.random.randn(5)})

In [5]: df

Out[5]:

key1 key2    data1       data2

0    a     one 0.280118 0.195369

1    a     two 1.166245 0.728360

2    b     one 0.701840 1.373510

3    b     two 0.485219 -1.124589

4    a    one -0.555356 0.899907

In [6]: grouped=df.groupby('key1')

In [7]: grouped

Out[7]:

D8>

In [8]: grouped['data1'].quantile(0.9)

Out[8]:

key1

a 0.989020

b 0.680178

Name: data1, dtype: float64

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

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

In [10]: def peak_to_peak(arr):

...: return arr.max()-arr.min()

...:

In [11]: grouped.agg(peak_to_peak)

Out[11]:

data1 data2

key1

a 1.721601 0.704539

b 0.216621 2.498099

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

In [12]: grouped.describe()

Out[12]:

data1      ...                           data2

count   mean      std ...           50%    75%        max

key1                                     ...

a           3.0 0.297002 0.860925 ... 0.72836 0.814134 0.899907

b           2.0 0.593530 0.153174 ... 0.12446 0.748985 1.373510

[2 rows x 16 columns]

在后面关于分组级运算和转换的那一节中,我们将详细说明这到底是怎么回事。

表:经过优化的GroupBy的方法

函数名                                 说明

count                      分组中非NA值的数量

sum                         非NA值的和

mean                       非NA值的平均值

median                    非NA值的算术中位数

std、var                   无偏(分母为n-1)标准差和方差

min、max                非NA值的最小值和最大值

prod                         非NA值的积

first、last                 第一个和最后一个非NA值

1.面向列的多函数应用

我们已经看到,对Series或DataFrame列的聚合运算其实就是使用aggregate(使用自定义函数)或调用诸如mean、std之类的方法。然而,我们可能希望对不同的列使用不同的聚合函数,或一次应用多个函数。其实这事也好办,我们将通过一些示例来进行说明。

In [37]: tips=DataFrame({'name':['calvin','kobe','michale','kate','mary'],'scor

...: e':np.random.randn(5),'sex':['Male','Male','Male','Female','Female'],'

...: smoker':['True','False','False','False','False'],'age':[30,36,20,24,8]

...: ,'ss_pct':['0.8','0.9','0.75','0.7','0.6']})

In [38]: grouped=tips.groupby(['sex','smoker'])

注意,对于上表中的那些描述统计,可以将函数名以字符串的形式传入:

In [39]: grouped.agg('mean')

Out[39]:

score    age

sex       smoker

Female  False  -0.039857 16

Male      False  -0.895152  28

True   -0.264493   30

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

In [40]: grouped.agg(['mean','std',peak_to_peak])

Out[40]:

score ...                                     age

mean          std ...                       std    peak_to_peak

sex       smoker ...

Female False -0.039857   0.547300 ...              11.313708      16

Male     False  -0.895152  0.271034 ...              11.313708      16

True -0.264493        NaN ...                          NaN          0

[3 rows x 6 columns]

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

In [41]: grouped.agg([('foo','mean'),('bar',np.std)])

Out[41]:

score                    age

foo         bar           foo       bar

sex         smoker

Female    False         -0.039857 0.547300 16 11.313708

Male        False         -0.895152 0.271034  28 11.313708

True         -0.264493        NaN   30   NaN

对于DataFrame,我们还可以定义一组应用于全部列的函数,或不同的列应用不同的函数。假设我们想要对score和age列计算三个统计信息:

In [1]: import numpy as np

In [2]: from pandas import Series,DataFrame

In [3]: tips=DataFrame({'name':['calvin','kobe','michale','kate','mary'],'score

...: ':np.random.randn(5),'sex':['Male','Male','Male','Female','Female'],'sm

...: oker':['True','False','False','False','False'],'age':[30,36,20,24,8],'s

...: s_pct':['0.8','0.9','0.75','0.7','0.6']})

In [4]: functions=['count','mean','max']

In [5]: grouped=tips.groupby(['sex','smoker'])

In [9]: result=grouped['score','age'].agg(functions)

In [10]: result

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值