【学习】数据聚合和分组运算【groupby】

分组键可以有多种方式,且类型不必相同

  • 列表或数组, 某长度与待分组的轴一样
  • 表示DataFrame某个列名的值
  • 字典或Series,给出待分组轴上的值与分组名之间的对应关系
  • 函数用于处理轴索引或索引中的各个标签

看一下示例:

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)})
dfOut[3]:       data1     data2 key1 key20  1.236062 -0.576333    a  one1 -1.925623 -0.874375    a  two2  1.472156 -0.005463    b  one3 -0.155766  2.318643    b  two4 -1.961012 -0.947843    a  one

按key1分组,并计算data1列的平均值。访问data1,并根据key1调用groupby

#按key1分组,访问data1的平均值
df['data1'].groupby(df['key1']).mean()Out[4]:
key1
a   -0.883525
b    0.658195
Name: data1, dtype: float64

数据根据分组键进行了聚合,产生一个新的Series,其索引为key1列中的唯一值

如果一次传入多个数组,就会得到不同的结果

df['data1'].groupby([df['key1'], df['key2']]).mean()
Out[5]:
key1  key2
a     one    -0.362475two    -1.925623
b     one     1.472156two    -0.155766
Name: data1, dtype: float64#这里,通过两个键进行了分组,得到的Series具有一个层次化索引(由唯一的键对组成)means.unstack()Out[7]: key2       one       twokey1                    a    -0.362475 -1.925623b     1.472156 -0.155766

GroupBy的size方法,可以返回一个含有分组大小的Series

df.groupby(['key1', 'key2']).size()
Out[13]:
key1  key2
a     one     2two     1
b     one     1two     1
dtype: int64

注意:分组键中的任何缺失 值都会被排除在结果之外

1、对分组进行迭代

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

for name, group in df.groupby('key1'):print(name)print(group)adata1     data2 key1 key2
0  1.236062 -0.576333    a  one
1 -1.925623 -0.874375    a  two
4 -1.961012 -0.947843    a  one
bdata1     data2 key1 key2
2  1.472156 -0.005463    b  one
3 -0.155766  2.318643    b  two

对于多重键的情况,元组的第一个元素将会是由键值组成的元组:

for (k1, k2), group in df.groupby(['key1', 'key2']):print(k1, k2)print(group)a onedata1     data2 key1 key2
0  1.236062 -0.576333    a  one
4 -1.961012 -0.947843    a  one
a twodata1     data2 key1 key2
1 -1.925623 -0.874375    a  two
b onedata1     data2 key1 key2
2  1.472156 -0.005463    b  one
b twodata1     data2 key1 key2
3 -0.155766  2.318643    b  two

你可以对这些数据片段做任何操作,将这些数据片段做成一个字典:

pieces = dict(list(df.groupby('key1')))pieces
Out[18]:
{'a':       data1     data2 key1 key20  1.236062 -0.576333    a  one1 -1.925623 -0.874375    a  two4 -1.961012 -0.947843    a  one, 'b':       data1     data2 key1 key22  1.472156 -0.005463    b  one3 -0.155766  2.318643    b  two}

pieces['b']Out[19]:       data1     data2 key1 key22  1.472156 -0.005463    b  one3 -0.155766  2.318643    b  two

groupby默认在axis = 0 上进行分组的,通过设置也可以在其他任何轴上进行分组

df.dtypes
Out[20]:
data1    float64
data2    float64
key1      object
key2      object
dtype: object

grouped = df.groupby(df.dtypes, axis = 1)dict(list(grouped))
Out[22]:
{dtype('float64'):       data1     data20  1.236062 -0.5763331 -1.925623 -0.8743752  1.472156 -0.0054633 -0.155766  2.3186434 -1.961012 -0.947843, dtype('O'):   key1 key20    a  one1    a  two2    b  one3    b  two4    a  one}

2、选取一个或一组列

对于由DataFrame产生的GroupBy对象,如果用一个(单个字符串)或一组(字符串数组)列名对其进行索引,就能实现选取部分列进行聚合的目的。也就是说

df.groupby('key1')['data1']
df.groupby('key1')['data2']df['data1'].groupby(df['key1'])
df['data2'].groupby(df['key2'])

尤其对于大数据集,很可能只需要对部分列进行聚合

df.groupby(['key1', 'key2'])[['data2']].mean()
Out[25]: data2
key1 key2
a    one  -0.762088two  -0.874375
b    one  -0.005463two   2.318643

这种索引操作所返回的对象是一个已分组的DataFrame或已分组的Series(如果传入的是标量形式的单个列名)

3、通过字典或Series进行分组

people.ix[2:3, ['b', 'c']] = np.nan #添加几个NA值

people
Out[29]: a         b         c         d         e
joe    -0.237225 -0.583231  2.506186  0.764346  2.628579
Steve  -0.125559 -0.185558 -0.226190 -1.624512 -0.988784
Wes     0.337773       NaN       NaN -2.489380 -0.064929
Jim     1.052081 -0.888873  1.227694  0.809077  1.031245
Travis  0.042581  0.793400  0.316565 -1.098852  0.129532

假设已知列的分组关系,并根据根据分组计算列的总计

#ix再回顾温习一下
mapping = {'a': 'red', 'b': 'red', 'c': 'blue', 'd': 'blue', 'e': 'red', 'f': 'orange'}
#现在只需将这个字典传给groupby即可
by_column = people.groupby(mapping, axis = 1)
by_column.sum()

Out[32]:             blue       redjoe     3.270531  1.808124Steve  -1.850702 -1.299900Wes    -2.489380  0.272844Jim     2.036771  1.194453Travis -0.782287  0.965513

Series也有同样的功能,被看做一个固定大小的映射,如果是Series作为分组键,则pandas会检查Series以确保其索引跟分组轴是对齐的

map_series = pd.Series(mapping)map_series
Out[34]:
a       red
b       red
c      blue
d      blue
e       red
f    orange
dtype: object

people.groupby(map_series, axis = 1).count()
Out[35]: blue  red
joe        2    3
Steve      2    3
Wes        1    2
Jim        2    3
Travis     2    3

4、通过函数进行分组

根据人名的长度进行分组,虽然可以求取一个字符串长度数组,但其实仅仅传入len函数就可以

people.groupby(len).sum()
Out[36]: a         b         c         d         e
3  1.152630 -1.472104  3.733879 -0.915957  3.594895
5 -0.125559 -0.185558 -0.226190 -1.624512 -0.988784
6  0.042581  0.793400  0.316565 -1.098852  0.129532

将函数跟数组、列表、字典、Series混合使用,因为任何东西最终都会被转换为数组

people.groupby([len, key_list]).min()  #这个没有理解
Out[38]: a         b         c         d         e
3 one -0.237225 -0.583231  2.506186 -2.489380 -0.064929two  1.052081 -0.888873  1.227694  0.809077  1.031245
5 one -0.125559 -0.185558 -0.226190 -1.624512 -0.988784
6 two  0.042581  0.793400  0.316565 -1.098852  0.129532

5、根据索引级别分组

层次化索引数据集最方便的地方就在于它能够根据索引级别进行聚合,要实现该目的,通过level关键字传入级别编号或名称即可

columns = pd.MultiIndex.from_arrays([['US', 'US', 'US', 'JP', 'JP'], [1, 3, 5, 1, 3]], names = ['cty', 'tenor'])hier_df = pd.DataFrame(np.random.randn(4, 5), columns = columns)hier_df
Out[41]:
cty          US                            JP
tenor         1         3         5         1         3
0     -0.248738  0.627953  2.071784  0.245686 -1.590562
1      1.723024  0.111605 -0.520688 -0.370661 -0.287072
2      0.061884 -0.502882  0.281061  0.083908  2.224092
3     -0.341529  0.945064 -0.785416 -0.443815  0.186289

hier_df.groupby(level = 'cty', axis =1).count()
Out[42]:
cty  JP  US
0     2   3
1     2   3
2     2   3
3     2   3

二、数据聚合

任何能够从数组产生标量值的数据转换过程。比如mean、 count 、min 以及 sum等。许多常见的聚合运算都有就地计算数据集统计信息的优化实现

quantile可以计算Series或DataFrame列的样本分位数
dfOut[43]:       data1     data2 key1 key20  1.236062 -0.576333    a  one1 -1.925623 -0.874375    a  two2  1.472156 -0.005463    b  one3 -0.155766  2.318643    b  two4 -1.961012 -0.947843    a  one
grouped = df.groupby('key1')
grouped
grouped['data1'].quantile(0.9)Out[47]: key1a    0.603725b    1.309364Name: data1, dtype: float64#注意:如果传入的百分位上没有值,则quantile会进行线性插值

实际上,GroupBy会高效地对Series进行切片,然后对各片调用piece, quantile(0.9), 最后将这些结果组成成最终结果

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

def peak_to_peak(arr):return arr.max() - arr.min()grouped.agg(peak_to_peak)
Out[49]: data1     data2
key1
a     3.197074  0.371510
b     1.627922  2.324107

#describe也可以这样用grouped.describe()
Out[50]: data1     data2
key1
a    count  3.000000  3.000000mean  -0.883525 -0.799517std    1.835701  0.196743min   -1.961012 -0.94784325%   -1.943318 -0.91110950%   -1.925623 -0.87437575%   -0.344781 -0.725354max    1.236062 -0.576333
b    count  2.000000  2.000000mean   0.658195  1.156590std    1.151114  1.643392min   -0.155766 -0.00546325%    0.251215  0.57556350%    0.658195  1.15659075%    1.065176  1.737617max    1.472156  2.318643

经过优化的groupby方法

1、面向列的多函数应用

#备注,tips没有下载下来,这里仅作为展示实例
grouped = tips.groupby(['sex', 'smoker'])
grouped_pct = grouped(['tip_pct'])
grouped_pct.agg('mean')
grouped_pct.agg('mean', 'std', peak_to_peak)
#以无索引的形式返回聚合数据
tips.groupby(['sex', 'smoker'], as_index = False).mean()

三、分组级运算和转换

transform和apply方法,它能够执行更多其他的分组运算

为一个DataFrame添加 一个用于存储各索引分组平均值的列,一个办法是先聚合再合并

df
Out[51]: data1     data2 key1 key2
0  1.236062 -0.576333    a  one
1 -1.925623 -0.874375    a  two
2  1.472156 -0.005463    b  one
3 -0.155766  2.318643    b  two
4 -1.961012 -0.947843    a  onek1_means = df.groupby('key1').mean().add_prefix('mean_')k1_means
Out[53]: mean_data1  mean_data2
key1
a      -0.883525   -0.799517
b       0.658195    1.156590

pd.merge(df, k1_means, left_on = 'key1', right_index = True)
Out[54]: data1     data2 key1 key2  mean_data1  mean_data2
0  1.236062 -0.576333    a  one   -0.883525   -0.799517
1 -1.925623 -0.874375    a  two   -0.883525   -0.799517
4 -1.961012 -0.947843    a  one   -0.883525   -0.799517
2  1.472156 -0.005463    b  one    0.658195    1.156590
3 -0.155766  2.318643    b  two    0.658195    1.156590

key = ['one', 'two', 'one', 'two',  'one']people.groupby(key).mean()
Out[57]: a         b         c         d         e
one  0.047710  0.105085  1.411375 -0.941295  0.897728
two  0.463261 -0.537216  0.500752 -0.407717  0.021231people.groupby(key).transform(np.mean)
Out[58]: a         b         c         d         e
joe     0.047710  0.105085  1.411375 -0.941295  0.897728
Steve   0.463261 -0.537216  0.500752 -0.407717  0.021231
Wes     0.047710  0.105085  1.411375 -0.941295  0.897728
Jim     0.463261 -0.537216  0.500752 -0.407717  0.021231
Travis  0.047710  0.105085  1.411375 -0.941295  0.897728

不难看出,transform会将一个函数应用到各个分组,然后将结果放置到适当的位置上

假设想从各分组中减去平均值,先创建一个距平化函数,然后将其传给transform

def demean(arr):return arr - arr.mean()demeaned = people.groupby(key).transform(demean)demeaned
Out[60]: a         b         c         d         e
joe    -0.284934 -0.688315  1.094810  1.705641  1.730852
Steve  -0.588820  0.351658 -0.726942 -1.216794 -1.010014
Wes     0.290063       NaN       NaN -1.548084 -0.962657
Jim     0.588820 -0.351658  0.726942  1.216794  1.010014
Travis -0.005129  0.688315 -1.094810 -0.157557 -0.768195

posted on 2017-09-13 22:37 一阵风,静! 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/yizhenfeng/p/7518111.html

【学习】数据聚合和分组运算【groupby】相关推荐

  1. pandas合并groupby_pandas数据聚合与分组运算——groupby方法

    简介 pandas中一类非常重要的操作是数据聚合与分组运算.通过groupby方法能够实现对数据集的拆分.统计.转换等操作,这个过程一气呵成. 在本文中,你将学到: 选取特定列分组: 对分组进行迭代: ...

  2. pandas 根据列名索引多列数据_Pandas 数据聚合与分组运算[groupby+apply]速查笔记

    利用Pandas将数据进行分组,并将各组进行聚合或自定义函数处理. Pandas中Groupby分组与聚合过程 导入模块 import pandas as pd 缩写 df表示Dataframe对象 ...

  3. 数据聚合与分组运算——GroupBy

    2019独角兽企业重金招聘Python工程师标准>>> pandas提供了一个灵活高效的groupby功能,它使你能以一种自然的方式对数据集进行切片.切块.摘要等操作. 根据一个或多 ...

  4. 【Python】GroupBy:数据聚合与分组运算

    [博客地址]:https://blog.csdn.net/sunyaowu315 [博客大纲地址]:https://blog.csdn.net/sunyaowu315/article/details/ ...

  5. 类的应用python平均分_【数据科学系统学习】Python # 数据分析基本操作[四] 数据规整化和数据聚合与分组运算...

    本篇内容为整理<利用Python进行数据分析>,博主使用代码为 Python3,部分内容和书本有出入. 在前几篇中我们介绍了 NumPy.pandas.matplotlib 三个库的基本操 ...

  6. Python数据聚合和分组运算(1)-GroupBy Mechanics

    前言 Python的pandas包提供的数据聚合与分组运算功能很强大,也很灵活.<Python for Data Analysis>这本书第9章详细的介绍了这方面的用法,但是有些细节不常用 ...

  7. 【学习经典】python 数据聚合与分组运算(part 2)

    本文的前半部分:python 数据聚合与分组运算(part 1) 4. 透视表和交叉表 透视表(pivot table)是各种电子表格程序和其他数据分析软件中一种常见的数据汇总工具.它根据一个或多个键 ...

  8. Python之数据聚合与分组运算

    Python之数据聚合与分组运算 1. 关系型数据库方便对数据进行连接.过滤.转换和聚合. 2. Hadley Wickham创建了用于表示分组运算术语"split-apply-combin ...

  9. vfp python_python foxpro数据聚合和分组运算——分组级运算和转换(3)

    数据聚合和分组运算--分组级运算和转换(3),有需要的朋友可以参考下. 1.假设我们想要为一个DataFrame添加一个用于存放各索引分组平均值的列,一个办法是先聚合再合并: >>> ...

最新文章

  1. 使用NVIDIA GRID vPC支持视频会议和算力工具
  2. iOS 使用fastlane自动化打包步骤
  3. linux x下载工具,Linux下强大的Axel下载工具
  4. 何钦铭c语言程序设计第八章,c语言程序设计(第3版)何钦铭-颜-晖-第8章--指针
  5. M-SOLUTIONS Programming Contest 2020总结
  6. ssm使用全注解实现增删改查案例——DeptMapperImpl
  7. Java Web学习总结(29)——Java Web中的Filter和Interceptor比较
  8. checkbox-复选框
  9. stm32mp1 Cortex M4开发篇6:TIM定时器中断
  10. 小米8SE 解BL锁教程 申请BootLoader解锁教程
  11. 中国最全亲戚关系图谱
  12. 技术岗的职业规划_银行信息技术岗职业规划范文
  13. android svg图片使用
  14. 菜单栏找不到不见了,页面和别人电脑显示的不一致,排查不出问题
  15. Excel公式向导,详细演艺多条件求平均值的操作
  16. 作业调度算法--先来先服务
  17. C/C++内存管理器
  18. 分享一个简单的抢购华为商城手机的js脚本,仅供学习交流
  19. vue3条码批量打印
  20. 如何修改计算机软件id号,详解使用软件快手修改ID的操作流程

热门文章

  1. MarkDown文本首行怎么缩进?
  2. 雅虎统计基础数据定义
  3. z301摄像头的驱动移植
  4. php文本输入框,html文本输入框代码是什么?如何创建html文本输入框
  5. 当中学的计算机老师需要什么学历,中学老师需要什么学历?
  6. url和超级url的区别
  7. C++ sizeof(struct)计算结构体大小
  8. JS读取字幕srt文件内容
  9. LNK1120/2001 无法解析的外部命令
  10. 服务器系列产品名称详解