一、groupby

类似excel的数据透视表,一般是按照行进行分组,使用方法如下。

  1. df.groupby(by=None, axis=0, level=None, as_index=True, sort=True, group_keys=True,
  2.      squeeze=False, observed=False, **kwargs)

分组得到的直接结果是一个DataFrameGroupBy对象。

  1. df = pd.DataFrame({'A':['zhao','li','wang','li','zhao'],
  2. 'B':['one','one','two','three','two'],
  3. 'C':np.arange(1,6),
  4. 'D':np.arange(6,11)})
  5. print(df)
  6. print(df.groupby('A'))
  7. print(type(df.groupby('A')))
  8. # A B C D
  9. # 0 zhao one 1 6
  10. # 1 li one 2 7
  11. # 2 wang two 3 8
  12. # 3 li three 4 9
  13. # 4 zhao two 5 10
  14. # <pandas.core.groupby.generic.DataFrameGroupBy object at 0x0000000001E6C550>
  15. # <class 'pandas.core.groupby.generic.DataFrameGroupBy'>

分组后的直接结果是一个可迭代对象,可迭代对象中的每一个元素都是一个元组,元组的第一个值为分组的名称,第二个值为DataFrame。可通过for或转换为list、元组查看每一个元素。

  1. for n,p in df.groupby('A'):
  2. print(type(p))
  3. print(n)
  4. print(p)
  5. print('-------------------------')
  6. # <class 'pandas.core.frame.DataFrame'>
  7. # li
  8. # A B C D
  9. # 1 li one 2 7
  10. # 3 li three 4 9
  11. # -------------------------
  12. # <class 'pandas.core.frame.DataFrame'>
  13. # wang
  14. # A B C D
  15. # 2 wang two 3 8
  16. # -------------------------
  17. # <class 'pandas.core.frame.DataFrame'>
  18. # zhao
  19. # A B C D
  20. # 0 zhao one 1 6
  21. # 4 zhao two 5 10
  22. # -------------------------

查看分组后的结果

通过get_group('分组名称')获取某一个分组的内容

groups是一个字典,字典的键为各分组名称,值为列表包含分组所在的索引行,可通过groups['分组名称']查看某一个分组所在的行

  1. print(df.groupby('A').get_group('zhao')) #获取分组后的zhao组
  2. # A B C D
  3. # 0 zhao one 1 6
  4. # 4 zhao two 5 10
  5.  
  6. print(df.groupby(['A','B']).groups)
  7. print(df.groupby(['A','B']).groups[('li', 'one')])
  8. # {('li', 'one'): Int64Index([1], dtype='int64'), ('li', 'three'): Int64Index([3], dtype='int64'), ('wang', 'two'): Int64Index([2], dtype='int64'), ('zhao', 'one'): Int64Index([0], dtype='int64'), ('zhao', 'two'): Int64Index([4], dtype='int64')}
  9. # Int64Index([1], dtype='int64')

get_group查看分组内容和groups查看分组所在行

size( )统计每个分组的长度

  1. print(df.groupby('A').size())
  2. print(type(df.groupby('A').size()))
  3. # A
  4. # li 2
  5. # wang 1
  6. # zhao 2
  7. # dtype: int64
  8. # <class 'pandas.core.series.Series'>

size统计分组的长度

分组可对单列或者多列进行,如果对多列进行分组,需要写在一个列表内。

  1. df = pd.DataFrame({'A':['zhao','li','wang','li','zhao'],
  2. 'B':['one','one','two','three','two'],
  3. 'C':np.arange(1,6),
  4. 'D':np.arange(6,11)})
  5. print(df.groupby('A').sum()) #以A列分组,对其他元素为数值的列进行求和,忽略非数值元素的列
  6. print('---------------------')
  7. print(df.groupby(['A','B']).sum()) #以A列和B列分组,对其他列求和,忽略非数值元素的列
  8. print('---------------------')
  9. print(df.groupby('A')['D'].sum()) #以A列分组,再对D列求和
  10. C D
  11. # A
  12. # li 6 16
  13. # wang 3 8
  14. # zhao 6 16
  15. # ---------------------
  16. # C D
  17. # A B
  18. # li one 2 7
  19. # three 4 9
  20. # wang two 3 8
  21. # zhao one 1 6
  22. # two 5 10
  23. # ---------------------
  24. # A
  25. # li 16
  26. # wang 8
  27. # zhao 16
  28. # Name: D, dtype: int32

groupby单列和多列分组

按照index分组,将index相同的分为一组,分组依据level=0

  1. df = pd.DataFrame({'data1':[1,2,3,4],'data2':[3,4,5,6],'A':[5,6,7,8],'B':[7,8,9,0]},index=[1,2,3,1])
  2. print(df) #groupby(level=0)表示将索引相同的行分为一组
  3. print(df.groupby(level=0).first()) #分组后组内第一个值
  4. print(df.groupby(level=0).last()) #分组后组内最后一个值
  5. print(df.groupby(level=0).max()) #分组后组内最大值
  6. print(df.groupby(level=0).min()) #分组后组内最小值
  7. print(df.groupby(level=0).sum()) #分组后组内元素的和
  8. print(df.groupby(level=0).mean()) #分组后组内元素的平均值
  9. print(df.groupby(level=0).median())#分组后组内元素的中位数
  10. print(df.groupby(level=0).count()) #分组后组内元素的个数
  11. print(df.groupby(level=0).std()) #分组后组内元素的方差
  12. print(df.groupby(level=0).prod()) #分组后组内元素的乘积
  13. print(df.groupby(level=0).describe())#分组后组内元素的countmeanstdmin25%、50%、75%。max

按index分组

按照index长度分组

  1. df = pd.DataFrame({'A':[1,2,3,4],'B':[3,4,5,6],'D':[5,6,7,8],'D':[7,8,9,0]},index=['a','ab','cd','e'])
  2. print(df)
  3. print(df.groupby(len).sum())
  4. # A B D
  5. # a 1 3 7
  6. # ab 2 4 8
  7. # cd 3 5 9
  8. # e 4 6 0
  9. # A B D
  10. # 1 5 9 7
  11. # 2 5 9 17

按照index长度分组

按照数据类型进行分组,df.dtypes可获得每个数据列的数据类型,数据类型是对列而言,因此按数据类型分组需指明axis=1

  1. df = pd.DataFrame({'data1':[1,2],'data2':[3,4],'A':['a','b'],'B':['c','d']})
  2. print(df)
  3. print(df.groupby(df.dtypes,axis=1).sum())
  4. for n,p in df.groupby(df.dtypes,axis=1):
  5. print(n)
  6. print(p)
  7. print('-------')
  8. # data1 data2 A B
  9. # 0 1 3 a c
  10. # 1 2 4 b d
  11. # int64 object
  12. # 0 4 ac
  13. # 1 6 bd
  14. # int64
  15. # data1 data2
  16. # 0 1 3
  17. # 1 2 4
  18. # -------
  19. # object
  20. # A B
  21. # 0 a c
  22. # 1 b d
  23. # -------

按照数据类型dtypes分组

按照字典分组,需定义一个字典,键为列名称,值为对应的分组名称,按照列分组需要指明axis=1

例如下面例子中的map,定义data1列和A列属于分组key1,data2列数组分组key2,B列属于分组key3

  1. df = pd.DataFrame({'data1':[1,2],'data2':[3,4],'A':['a','b'],'B':['c','d']})
  2. map = {'data1':'key1','data2':'key2','A':'key1','B':'key3'}
  3. for i,p in df.groupby(map,axis=1):
  4. print(i)
  5. print(p)
  6. print('----------')
  7. # key1
  8. # data1 A
  9. # 0 1 a
  10. # 1 2 b
  11. # ----------
  12. # key2
  13. # data2
  14. # 0 3
  15. # 1 4
  16. # ----------
  17. # key3
  18. # B
  19. # 0 c
  20. # 1 d
  21. # ----------

按照字典分组

多函数计算agg(函数1,函数2)

对分组后的每个组既进行第一个函数的计算,又进行第二个函数的计算。

  1. df = pd.DataFrame({'a':[1,2,3,1],'b':['a','b','a','b'],'c':np.arange(3,7),'d':np.arange(2,6)})
  2. print(df)
  3. print(df.groupby('a').agg(['mean','sum'])) #b列为非数值,忽略
  4. print(df.groupby('b').agg([np.sum,np.mean]))
  5. # a b c d
  6. # 0 1 a 3 2
  7. # 1 2 b 4 3
  8. # 2 3 a 5 4
  9. # 3 1 b 6 5
  10. # c d
  11. # mean sum mean sum
  12. # a
  13. # 1 4.5 9 3.5 7
  14. # 2 4.0 4 3.0 3
  15. # 3 5.0 5 4.0 4
  16. # a c d
  17. # sum mean sum mean sum mean
  18. # b
  19. # a 4 2.0 8 4 6 3
  20. # b 3 1.5 10 5 8 4

分组后多函数计算agg

多函数计算后的默认column为函数名称,也可以通过字典自定义column。

  1. df = pd.DataFrame({'a':[1,2,3,1],'b':['a','b','a','b'],'c':np.arange(3,7),'d':np.arange(2,6)})
  2. print(df.groupby('b')['c'].agg({'result_sum':np.sum,'result_mean':np.mean}))
  3. # result_sum result_mean
  4. # b
  5. # a 8 4
  6. # b 10 5

多函数计算后自定义列名称

二、transform

上述groupby如果通过行分组再进行求和、均值等,会出现结果与原对象的行数不一致的情况,而通过transform得到的结果与原对象的结果行数一致。

  1. df = pd.DataFrame({'A':['zhao','li','wang','li','zhao'],
  2. 'B':['one','one','two','two','three'],
  3. 'C':np.arange(1,6),
  4. 'D':np.arange(5,10)})
  5. print(df)
  6. print(df.groupby('B').mean()) #只包含one、two、three三行
  7. print(df.groupby('B').transform(np.mean)) #结果为5行,B列内容相同的行的结果相同
  8. # A B C D
  9. # 0 zhao one 1 5
  10. # 1 li one 2 6
  11. # 2 wang two 3 7
  12. # 3 li two 4 8
  13. # 4 zhao three 5 9
  14. # C D
  15. # B
  16. # one 1.5 5.5
  17. # three 5.0 9.0
  18. # two 3.5 7.5
  19. # C D
  20. # 0 1.5 5.5
  21. # 1 1.5 5.5
  22. # 2 3.5 7.5
  23. # 3 3.5 7.5
  24. # 4 5.0 9.0

transform()演示

三、applay

上述groupby分组后都是使用python定义好的sum、mean、max等进行统计计算,apply可以自定义统计方法。

  1. def func(df,n):
  2. return ***
  3.  
  4. df.groupby('*').apply(func,n)
  5.  
  6. #自定义函数func,第一个参数为pandas对象,并返回值
  7. #分组后使用apply函数,将自定义函数的名称作为第一个参数,第二个参数传递给自定义函数的第二个参数
  1. df = pd.DataFrame({'A':['zhao','li','wang','li','zhao','zhao'],
  2. 'B':['one','one','two','two','three','two'],
  3. 'C':np.arange(1,7),
  4. 'D':np.arange(4,10)})
  5. def f(d,n):
  6. return d.sort_index()[:n] #按照索引排序,并返回前n行
  7. print(df)
  8. print(df.groupby('A').apply(f,2)) #按照A分组,对结果按索引排序,并返回每组的前n行
  9. A B C D
  10. # 0 zhao one 1 4
  11. # 1 li one 2 5
  12. # 2 wang two 3 6
  13. # 3 li two 4 7
  14. # 4 zhao three 5 8
  15. # 5 zhao two 6 9
  16. # A B C D
  17. # A
  18. # li 1 li one 2 5
  19. # 3 li two 4 7
  20. # wang 2 wang two 3 6
  21. # zhao 0 zhao one 1 4
  22. # 4 zhao three 5 8

apply()自定义统计方法

四、透视表pivot_table()、pivot()

  1. pivot_table(self, values=None, index=None, columns=None, aggfunc='mean',
  2. fill_value=None, margins=False, dropna=True, margins_name='All')

可类比excel的数据透视表进行理解,使用方法pd.pivot_table( df , ...),或直接使用df.pivot_table( ... )

  • values:透视后对哪一列进行计算
  • index:按照哪一列进行分组
  • columns:透视后除了values,还包含哪些列
  • aggfunc:对values进行计算的方法,默认为平均值
  • fill_value:对空值使用fill_value指定的值填充,默认为NaN
  1. import numpy as np
  2. import pandas as pd
  3. date = ['2019/5/1','2019/5/2','2019/5/3']*3
  4. df = pd.DataFrame({'date':pd.to_datetime(date),'key':list('abcbacbca'),'value':np.arange(1,10)})
  5. print(df)
  6. print(df.pivot_table(index='date',values='value',columns='key',aggfunc=np.sum))
  7. print(df.pivot_table(index=['date','key'],values='value',aggfunc=np.sum))
  8. # date key value
  9. # 0 2019-05-01 a 1
  10. # 1 2019-05-02 b 2
  11. # 2 2019-05-03 c 3
  12. # 3 2019-05-01 b 4
  13. # 4 2019-05-02 a 5
  14. # 5 2019-05-03 c 6
  15. # 6 2019-05-01 b 7
  16. # 7 2019-05-02 c 8
  17. # 8 2019-05-03 a 9
  18. # key a b c
  19. # date
  20. # 2019-05-01 1.0 11.0 NaN
  21. # 2019-05-02 5.0 2.0 8.0
  22. # 2019-05-03 9.0 NaN 9.0
  23. # value
  24. # date key
  25. # 2019-05-01 a 1
  26. # b 11
  27. # 2019-05-02 a 5
  28. # b 2
  29. # c 8
  30. # 2019-05-03 a 9
  31. # c 9

数据透视表pivot_table()

pivot()也是用来生成透视表的,结果为一个二维的表格,结果中可能会存在空值,但是与pivot_table()用法和结果稍有不同。

pivot(data, index=None, columns=None, values=None),使用方法pd.pivot(df,...)或者df.pivot()

index 透视行

columns 透视列

values 对哪一列进行透视

  1. date = ['2019/5/1','2019/5/2','2019/5/3']*3
  2. df = pd.DataFrame({'date':pd.to_datetime(date),'key':list('abcbabccd'),'value':np.arange(1,10)})
  3. res = pd.pivot(df,'date','key','value')
  4. print(res)
  5. # key a b c d
  6. # date
  7. # 2019-05-01 1.0 4.0 7.0 NaN
  8. # 2019-05-02 5.0 2.0 8.0 NaN
  9. # 2019-05-03 NaN 6.0 3.0 9.0

数据透视pivot()

五、交叉表crossta()

交叉表默认用来统计元素出现的频数,使用方法pd.crosstab(Seris1,Seris2)

  1. crosstab(index, columns, values=None, rownames=None, colnames=None, aggfunc=None,
          margins=False, margins_name='All', dropna=True, normalize=False)
  • index:行的统计依据
  • columns:列的统计依据
  • values:在行为index、列为columns的基础上,对values指定的列进行统计,默认为None,表示统计频数
  • aggfunc:统计方法,agggunc和values必须同时使用
  • normalize:默认为False,值设置为True表示统计频率
  • margins:默认为False,值设置为True表示对结果添加一列,对每列的和进行统计,同时添加一行,对每行的和进行统计
  • rownames和colnames:默认为None,即显示index和columns的名称
  1. df = pd.DataFrame([[1,2,3,1,3],[2,'a','a',2,1],[3,np.nan,'a','b',2],[np.nan,'a','b',1,2],[4,1,'c','b',2]],columns=['A','B','C','D','E'])
  2. print(pd.crosstab(df['A'],df['B'])) #表示统计A为1且B为1出现的次数,A为2且B为1出现的次数,A为4且B为1出现的次数……
  3. # B 1 2 a
  4. # A
  5. # 1.0 0 1 0
  6. # 2.0 0 0 1
  7. # 4.0 1 0 0

可以看到A为np.nan、B为np.nan的两行在统计时都被忽略了。

normalize=True会将上述结果的非0值显示为小数试的百分比

  1. print(pd.crosstab(df['A'],df['B'],normalize=True))
  2. # B 1 2 a
  3. # A
  4. # 1.0 0.000000 0.333333 0.000000
  5. # 2.0 0.000000 0.000000 0.333333
  6. # 4.0 0.333333 0.000000 0.000000

同时指定values=df['E']和aggfunc=np.sum,表示在A和B对应值得条件下,对E列求和

  1. print(pd.crosstab(df['A'],df['B'],values=df['E'],aggfunc=np.sum))
  2. # B 1 2 a
  3. # A
  4. # 1.0 0 1 0
  5. # 2.0 0 0 1
  6. # 4.0 1 0 0

margins增加行和列的总数统计

  1. print(pd.crosstab(df['A'],df['B']))
  2. print(pd.crosstab(df['A'],df['B'],margins=True))
  3. # B 1 2 a
  4. # A
  5. # 1.0 0 1 0
  6. # 2.0 0 0 1
  7. # 4.0 1 0 0
  8.  
  9. # B 1 2 a All
  10. # A
  11. # 1.0 0 1 0 1
  12. # 2.0 0 0 1 1
  13. # 4.0 1 0 0 1
  14. # All 1 1 1 3

rownames和colnames自定义结果显示的行和列名称

  1. print(pd.crosstab(df['A'],df['B'],rownames=['AAA'],colnames=['BBB']))
  2. # BBB 1 2 a
  3. # AAA
  4. # 1.0 0 1 0
  5. # 2.0 0 0 1
  6. # 4.0 1 0 0

pandas之groupby分组与pivot_table透视的更多相关文章

  1. pandas之groupby分组与pivot_table透视表

    zhuanzi: https://blog.csdn.net/qq_33689414/article/details/78973267 pandas之groupby分组与pivot_table透视表 ...

  2. pandas获取groupby分组里最大值所在的行,获取第一个等操作

    pandas获取groupby分组里最大值所在的行 10/May 2016 python pandas pandas获取groupby分组里最大值所在的行 如下面这个DataFrame,按照Mt分组, ...

  3. Pandas之groupby分组

    释义 groupby用来分组,调用groupby 之后返回pandas.core.groupby.generic.DataFrameGroupBy,其实就是由一个个格式为(key, 分组后的dataf ...

  4. pandas聚合和分组运算——GroupBy技术(1)

    数据聚合与分组运算——GroupBy技术(1),有需要的朋友可以参考下. pandas提供了一个灵活高效的groupby功能,它使你能以一种自然的方式对数据集进行切片.切块.摘要等操作.根据一个或多个 ...

  5. Pandas | GroupBy 分组

    任何分组(groupby)操作都涉及原始对象的以下操作之一: 分割对象 应用一个函数 结合的结果 在许多情况下,我们将数据分成多个集合,并在每个子集上应用一些函数.在应用函数中,可以执行以下操作: 聚 ...

  6. pandas学习(数据分组与分组运算、离散化处理、数据合并)

    pandas学习(数据分组与分组运算.离散化处理.数据合并) 目录 数据分组与分组运算 离散化处理 数据合并 数据分组与分组运算 GroupBy技术:实现数据的分组,和分组运算,作用类似于数据透视表 ...

  7. 深入理解和运用Pandas的GroupBy机制——理解篇

    GroupBy是Pandas提供的强大的数据聚合处理机制,可以对大量级的多维数据进行透视,同时GroupBy还提供强大的apply函数,使得在多维数据中应用复杂函数得到复杂结果成为可能(这也是个人认为 ...

  8. pandas应用之分组因子暴露和分位数分析

    pandas应用之分组因子暴露和分位数分析 首先感谢原书作者Mes McKinney和batteryhp网友的博文, 俺在此基础上继续探索python的神奇功能. 用A股的实际数据, 以书里的代码为蓝 ...

  9. pandas中的分组技术

    目录 1  分组操作 1.1  按照列进行分组 1.2  按照字典进行分组 1.3  根据函数进行分组 1.4  按照list组合 1.5  按照索引级别进行分组 2  分组运算 2.1  agg 2 ...

随机推荐

  1. python 异常类型大全

    try except 处理异常真舒服!!!

  2. windows虚拟机安装mac

    在虚拟机上安装mac 首先参考这个:http://jingyan.baidu.com/article/7f41ecec039936593d095c87.html 如果完成不了,请参看下面的.     ...

  3. js事件入门(1)

    1.事件相关概念 1.1 什么是事件? 事件是用户在访问页面时执行的操作,也就是用户访问页面时的行为.当浏览器探测到一个事件时,比如鼠标点击或者按键.它可以触发与这个事件相关的JavaScript对象 ...

  4. SpringBoot启动源码及自定义starter

    为什么springboot工程能够在mian方法中完成启动呢?需要大家掌握的有几个点:1.SPISPI在springboot中是去读取META-INF/spring.factories目录的配置文件内 ...

  5. python中的守护线程

    什么是守护线程:在后台运行,为其他线程提供服务的线程成为守护线程. 为什么要引入守护线程: thread模块不支持守护线程的概念,当主线程退出时,所有的子线程都将终止,不管它们是否仍在工作, 如果你不 ...

  6. HTTPS协议详解(三):PKI 体系

    转自:https://blog.csdn.net/hherima/article/details/52469488 1.RSA身份验证的隐患    身份验证和密钥协商是TLS的基础功能,要求的前提是合 ...

  7. 《The Design of a Practical System for Fault-Tolerant Virtual Machines》论文研读

    VM-FT 论文研读 说明:本文为论文 <The Design of a Practical System for Fault-Tolerant Virtual Machines> 的个人 ...

  8. python 如何判断一组数据是否符合正态分布

    正态分布: 若随机变量x服从有个数学期望为μ,方差为σ2 的正态分布,记为N(μ,σ) 其中期望值决定密度函数的位置,标准差决定分布的幅度,当υ=0,σ=0 时的正态分布是标准正态分布 判断方法有画图 ...

  9. 云小课 | “VPC连接”知多少

    摘要:华为云提供了丰富的网络服务,可满足多种网络互连场景. 同Region的两个VPC怎么连通?” “跨Region的两个VPC又怎么连通?” “VPC内的ECS搭建了一个应用,需要访问Interne ...

  10. day46 mysql进阶

    目录 一.约束条件 1 default默认值 2 unique唯一 2.1 单列唯一 2.2 联合唯一 3 primary key主键 3.1 主键的基本使用 3.2 主键的特性 4 auto_inc ...