Pandas_06数据聚合与分组运算

17 篇文章 2 订阅

一、分组 (groupby)

(一) groupby 对象

1、分组运算过程:split->apply->combine

拆分:根据提供的一个或多个键拆分成多组
应用:每个分组运行的计算规则
合并:把每个分组的计算结果合并起来
在这里插入图片描述

2、分组操作:

groupby()进行分组,GroupBy对象没有进行实际运算,只是包含分组的中间数据

数据如下:

在这里插入图片描述

  • 按列分组 obj.groupby(‘label’)

此时label为分组后数据的索引

grouped =book_data.groupby('original_publication_year')
# 此时的grouped 是一个groupby对象,实际上还没进行任何计算,只是含有一些关于分组键的中间数据
grouped

out:

<pandas.core.groupby.groupby.DataFrameGroupBy object at 0x000001D92551A400>
  • 按列多重分组 obj.groupby([‘label1’,‘label2’])

此时label1、label2为分组后数据的多层索引

grouped =book_data.groupby(['original_publication_year','authors'])
  • 指定要进行分组数据 obj[‘columns’].groupby(‘label’)

不一定每列数据都是需要的,可以选出满足分组需求的列数据

name = ['original_publication_year','language_code','books_count','ratings_count']

# 分组的列一定要包含在name当中
grouped =book_data[name].groupby(['original_publication_year'])

2、分组运算:

对GroupBy对象进行分组运算/多重分组运算

  • 计算分组平均值(调用groupby的mean方法)

按单列分组

grouped =book_data.groupby('original_publication_year')
# 计算分组平均值,并查看前五行数据
grouped.mean().head()

out:
可以看出结果中并没有authors列,因为它不是数值类型的数据。
在这里插入图片描述

按多列分组:

grouped =book_data.groupby(['original_publication_year','authors'])
# 查看分组后各数值类型列的均值,并查看后20条数据
grouped.mean().tail(20)

可以看出先按original_publication_year分组,再按authors分组,且这两个分组字段为分组后数据的索引。

在这里插入图片描述

  • 计算每个分组的最大数(调用groupby的max方法)
grouped.max().head()
  • 计算每个分组的元素个数(调用groupby的size方法)
grouped.size().head()

在这里插入图片描述

(二) 对分组进行迭代

groupby对象支持迭代,可产生一组二元数组(由分组名和数据块组成)

  • 单键的情况下
name = ['original_publication_year','language_code','books_count','ratings_count']
grouped =book_data[name].groupby(['original_publication_year'])

# 对分组数据进行遍历
for name,group in book_data.groupby('original_publication_year'):
    print(name)
    print(group)

out:
如图:1962、1963为分组名,对应的下面的数据为数据块
在这里插入图片描述

  • 多重键的情况下

元组的第一个元素将会是由键值组成的元组

name = ['original_publication_year','language_code','books_count','ratings_count']
grouped =book_data[name].groupby(['original_publication_year','language_code'])

for (name1,name2),group in grouped:
    print(name1,name2)
    print(group)

out:

在这里插入图片描述

(三)GroupBy对象可以转换成列表或字典

1、GroupBy对象转换list

print(list(grouped))

列表的每个元素为一个分组数据,分组数据以元组形式存储

在这里插入图片描述

2、GroupBy对象转换dict

print(dict(list(grouped)))

在这里插入图片描述

(四)按数据类型分组

显示DataFrame各列的数据类型

book_data1.dtypes

在这里插入图片描述根据数据类型进行分组

grouped1 = book_data1.groupby(book_data1.dtypes,axis = 1)
grouped1.describe()

在这里插入图片描述

(五)通过字典或Series进行分组

1、通过Series分组

# 通过Series分组
data = np.random.randint(0,20,(5,4))
data = pd.DataFrame(data,index=['a','b','c','d','e'],columns=[1,2,3,4])
data

在这里插入图片描述2、通过字典分组

# 通过字典分组(知道每一列对应的分组关系)
mapping={1:'red',2:'blue',3:'red',4:'blue'}
grouped2 = data.groupby(mapping,axis = 1)
grouped2.describe()

在这里插入图片描述

grouped2.sum()

在这里插入图片描述

(六)通过函数进行分组

任何被当作分组键的函数都会在各索引值上被调用一次,其返回值被用作分组的名称

数据:
book_data1.head()

# 根据作者名字的长度进行分组
book_data1.groupby(len).sum().head()

在这里插入图片描述

(七)通过索引级别进行分组

层次化索引数据集最方便的地方就在于她能根据索引级别进行聚合。要实现该目的,通过level关键字传入接比如编号或名称即可
在这里插入图片描述
传入索引编号

# 此处为行索引,如果是列索引,axis=1
book_data1.groupby(level = 1).count()

传入索引名称

book_data1.groupby(level = 'language_code').count()

以上两种写法作用相同,结果如下:

在这里插入图片描述

二、聚合 (Aggregation)

数组产生标量值的数据转换过程,如mean()、count()等
常用于对分组后的数据进行计算

1、内置的聚合函数

sum(), mean(), max(), min(), count(), size(), describe()

在这里插入图片描述

book_data1.groupby('language_code')['books_count'].min()

在这里插入图片描述
2、grouped.agg(func)

func的参数为groupby索引对应的记录
可自定义函数,传入agg方法中

在这里插入图片描述

# 自定义函数
def diff(df):
    """
       极差
    """
    return df.max() - df.min()
    
# agg传入自定义函数
grouped1.agg(diff)

在这里插入图片描述

  • 多函数应用
# 使用二元元组作为返回后的数据列名
grouped1.agg([('极差',diff),('最大值','max'),('最小值','min')])

在这里插入图片描述

  • 对不同的列分别作用不同的聚合函数(使用字典)
mapping = {'books_count':['mean','median'],'ratings_count':'max'}
grouped1.agg(mapping)

在这里插入图片描述

三、数据的分组级运算和转换

聚合只是分组运算的其中一种,它是数据转换的一个特例。
数据转换接受将一维数组简化为标量。
transform和apply方法能够执行更多其他的分组运算。

  • grouped.transform(func)

transform的计算结果和原始数据的形状保持一致(返回与数据同样长度的行)

grouped2 =book_data2[['language_code','average_rating','ratings_count']].groupby('language_code').transform(max)

返回的行数据长度与元数据长度一致
在这里插入图片描述

  • grouped.apply(func)

func函数也可以在各分组上分别调用,最后结果通过pd.concat组装到一起(数据合并)
可以按照行、列进行聚合
在这里插入图片描述
1. 产生层级索引:外层索引是分组名,内层索引是df_obj的行索引

def top_n(df, n=1,column ='average_rating' ):
    """
        返回每个分组按 column 的 top n 数据
    """
    return df.sort_values(by=column, ascending=False)[:n]
    
book_data3.groupby('language_code').apply(top_n)

外层language_code是分组名
book_data3.groupby('language_code').apply(top_n)

2、 禁止层级索引, group_keys=False

# 禁止层级索引, group_keys=False
grouped3 = book_data3.groupby('language_code' ,group_keys=False).apply(top_n, n=2, column='ratings_count')
grouped3.head()

在这里插入图片描述
按列计算:

book_data3[['average_rating','ratings_count']].apply(np.sum,axis = 1)

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值