Pandas中的GroupBy分组及agg()分组聚合

Pandas中的分组聚合功能其实类似SQL语句中的group by自己及聚合函数用法。具体地,Pandas中支持的分组主要有以下几种形式。依次介绍如下:

1. 通过函数进行分组

pandas中可以通过定义函数对数据进行分组。

import pandas as pd
import numpy as np
def odd(num):
    return (num%2)==0
data=pd.DataFrame(np.arange(21).reshape(3,7),columns=list('ABCDEFG'))
print("第一种分组结果:")
for key,group in data.groupby(odd):#相当于依据data的索引值在odd函数上的运行结果作为分类标准
    print(key)
    print(group)
print("第二种分组结果:")
for key,group in data.groupby(odd(data['B'])):#相当于依据B列在odd函数的运行结果作为分类标准
    print(key)
    print(group)

具体的代码运行结果如下:

Pandas中的GroupBy分组及agg()分组聚合_第1张图片

关于使用自定义对数据进行分组时,可以总结一下两点:

  •  首先,除了自定义的函数,python中的内建函数,比如len等,也可以直接用来进行分组。(此处并没有举例)
  • 其次,这些函数不仅可以作用在索引列上,也可以自己指定作用列。
  • 最后,指定了自定义函数的作用列之后,作用列中的每个值都会传入到函数中执行。并根据其函数运行结果对原始数据进行分组。

2.在axis=1轴上进行分组

Pandas中使用groupby时默认是在axis=0轴上进行分组的,也可以通过设置在axis=1轴上进行分组。

import pandas as pd
import numpy as np
def odd(num):
    return int(num)%2==0
data=pd.DataFrame(np.arange(20).reshape(4,5),index=list('1234'),columns=list('12345'))
print("原始数据:")
print(data)
data_axis0=data.groupby(odd,axis=0)#默认依据index在odd上的运行结果进行分组
print("按axis=0进行分组结果如下:")
for key,group in data_axis0:
    print(key)
    print(group)
data_axis1=data.groupby(odd,axis=1)#默认依据column在odd上的运行结果进行分组
print("按axis=1进行分组结果如下:")
for key,group in data_axis1:
    print(key)
    print(group)

代码运行结果如下:

Pandas中的GroupBy分组及agg()分组聚合_第2张图片

注意:

  • pands中的两种数据类型DataFrame和Series都支持GroupBy操作,但Series只支持在axis=0轴上进行操作。因为Series没有axis=1轴。
  • 若未设置axis参数,默认按axis=0轴进行聚合。

3. 使用其他数据进行分组

前面介绍的对数据进行分组,主要是在两类数据上进行的,一类是默认的index值或column值,还有一类就是dataframe中某一类或某一行的值。除了这两类之外,pandas还可以依据非dataframe中的数据对dataframe进行分组。

import pandas as pd
import numpy as np
data=pd.DataFrame(np.arange(30).reshape(5,6),index=list('12345'),columns=list('ABCDEF'))
print(data)
date_list=[2004,2005,2006,2005,2004]
data_1=data.groupby(date_list)
print("分组结果如下:")
for key,group in data_1:
    print(key)
    print(group)

代码运行结果如下:

Pandas中的GroupBy分组及agg()分组聚合_第3张图片

注意:

  • 首先,在这种写法中不能设置axis参数(笔者是在python3.6版本进行的实验)。原因暂且不明。
  • 其次,从代码运行结果进行反推可以得出以下两个结论:1.聚合默认是在axis=0轴进行的。2.代码中的date_list中的每个元素按照顺序与dataframe中的记录一一对应。所以date_list的长度要和dataframe中的记录数一致。

除了使用上述List类型的数据作为分组依据,还可以使用Series和字典作为分组依据。下面仅以字典类型为例:

import pandas as pd
import numpy as np
data=pd.DataFrame(np.arange(20).reshape(4,5),index=list('1234'),columns=list('12345'))
by_dict={'1':'red','2':'yellow','3':'yellow','4':'black','5':'white'}
by_dict1={'1':'red','2':'yellow','3':'yellow','5':'white'}
data_1=data.groupby(by_dict)
print("按by_dict分组的结果:")
for key,group in data_1:
    print(key)
    print(group)
data_2=data.groupby(by_dict1)
print("按by_dict1分组的结果:")
data_3=data.groupby(by_dict1)
for key,group in data_3:
    print(key)
    print(group)

代码运行结果如下:

Pandas中的GroupBy分组及agg()分组聚合_第4张图片

注意:

  • 使用字典或Series作为依据对数据进行分组时,如果行索引或列索引在分组依据(代码中的by_dict和by_dict1变量)中并没有找到对应关系,则对应的行或列是不参与最终的分组的(不是自成一组,可以从by_dict1分组的结果中看出此结论)。
  • 分组依据中可以出现行索引或列索引中没有出现的值。比如by_dict1中的5
  • 使用Series和字典时,可以设置axis参数。

4.agg()或者aggregate()函数

Pandas和Series使用Groupby技术之后可以在得到的数据上进行一些数值型的聚合计算。通常的聚合方法包括以下几种:

count(求数据量)、sum(求和)、mean(求均值)、median(求中位数)、std(求方差)、var(求标准差)、min(求最小值)、max(求最大值)、prod(求积)、first(求第一个值)、last(求最后一个值)。

以上这些聚合方法都会排除每个分组内的NaN值。当然也可以自定义聚合函数,但是自定义聚合函数的执行效率一般比较低。因为以前在使用agg()函数的时候一直把握不准传入聚合函数中的到底是什么样子的数据,所以每次使用自定义函数进行聚合的时候都会先将传入聚合函数中的数据先print()输出。

import pandas as pd
import numpy as np
df1=pd.DataFrame({
    'Data1':np.random.randint(0,10,5),
    'Data2':np.random.randint(10,20,5),
    'key1':list("aabba"),
    'key2':list('xyyxy')
})
def peak_range(df):
    print(df)
    return df.max()-df.min()
df1.groupby('key1').agg(peak_range)

首先我们先来看看传送到聚合函数中的数据。从以下试验结果中可以发现,聚合函数是按列接受每个groupby分组中的数据。

Pandas中的GroupBy分组及agg()分组聚合_第5张图片

下面来看看聚合函数的运行结果,如下。

Pandas中的GroupBy分组及agg()分组聚合_第6张图片

 

你可能感兴趣的:(Python)