pandas之groupby分组与pivot_table透视

一、groupby

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

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

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

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

 

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

for n,p in df.groupby('A'):print(type(p))print(n)print(p)print('-------------------------')
# <class 'pandas.core.frame.DataFrame'>
# li
#     A      B  C  D
# 1  li    one  2  7
# 3  li  three  4  9
# -------------------------
# <class 'pandas.core.frame.DataFrame'>
# wang
#       A    B  C  D
# 2  wang  two  3  8
# -------------------------
# <class 'pandas.core.frame.DataFrame'>
# zhao
#       A    B  C   D
# 0  zhao  one  1   6
# 4  zhao  two  5  10
# -------------------------
查看分组后的结果

 

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

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

print(df.groupby('A').get_group('zhao'))  #获取分组后的zhao组
#       A    B  C   D
# 0  zhao  one  1   6
# 4  zhao  two  5  10print(df.groupby(['A','B']).groups)
print(df.groupby(['A','B']).groups[('li', 'one')])
# {('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')}
# Int64Index([1], dtype='int64')
get_group查看分组内容和groups查看分组所在行

 

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

print(df.groupby('A').size())
print(type(df.groupby('A').size()))
# A
# li      2
# wang    1
# zhao    2
# dtype: int64
# <class 'pandas.core.series.Series'>
size统计分组的长度

 

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

df = pd.DataFrame({'A':['zhao','li','wang','li','zhao'],'B':['one','one','two','three','two'],'C':np.arange(1,6),'D':np.arange(6,11)})
print(df.groupby('A').sum())   #以A列分组,对其他元素为数值的列进行求和,忽略非数值元素的列
print('---------------------')
print(df.groupby(['A','B']).sum())   #以A列和B列分组,对其他列求和,忽略非数值元素的列
print('---------------------')
print(df.groupby('A')['D'].sum())   #以A列分组,再对D列求和
      C   D
# A          
# li    6  16
# wang  3   8
# zhao  6  16
# ---------------------
#             C   D
# A    B           
# li   one    2   7
#      three  4   9
# wang two    3   8
# zhao one    1   6
#      two    5  10
# ---------------------
# A
# li      16
# wang     8
# zhao    16
# Name: D, dtype: int32
groupby单列和多列分组

 

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

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])
print(df)  #groupby(level=0)表示将索引相同的行分为一组
print(df.groupby(level=0).first()) #分组后组内第一个值
print(df.groupby(level=0).last())  #分组后组内最后一个值
print(df.groupby(level=0).max())   #分组后组内最大值
print(df.groupby(level=0).min())   #分组后组内最小值
print(df.groupby(level=0).sum())   #分组后组内元素的和
print(df.groupby(level=0).mean())  #分组后组内元素的平均值
print(df.groupby(level=0).median())#分组后组内元素的中位数
print(df.groupby(level=0).count())   #分组后组内元素的个数
print(df.groupby(level=0).std())     #分组后组内元素的方差
print(df.groupby(level=0).prod())    #分组后组内元素的乘积
print(df.groupby(level=0).describe())#分组后组内元素的count、mean、std、min、25%、50%、75%。max
按index分组

 

按照index长度分组

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'])
print(df)
print(df.groupby(len).sum())
#     A  B  D
# a   1  3  7
# ab  2  4  8
# cd  3  5  9
# e   4  6  0
#    A  B   D
# 1  5  9   7
# 2  5  9  17
按照index长度分组

 

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

df = pd.DataFrame({'data1':[1,2],'data2':[3,4],'A':['a','b'],'B':['c','d']})
print(df)
print(df.groupby(df.dtypes,axis=1).sum())
for n,p in df.groupby(df.dtypes,axis=1):print(n)print(p)print('-------')
#    data1  data2  A  B
# 0      1      3  a  c
# 1      2      4  b  d
#    int64 object
# 0      4     ac
# 1      6     bd
# int64
#    data1  data2
# 0      1      3
# 1      2      4
# -------
# object
#    A  B
# 0  a  c
# 1  b  d
# -------
按照数据类型dtypes分组

 

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

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

df = pd.DataFrame({'data1':[1,2],'data2':[3,4],'A':['a','b'],'B':['c','d']})
map = {'data1':'key1','data2':'key2','A':'key1','B':'key3'}
for i,p in df.groupby(map,axis=1):print(i)print(p)print('----------')
# key1
#    data1  A
# 0      1  a
# 1      2  b
# ----------
# key2
#    data2
# 0      3
# 1      4
# ----------
# key3
#    B
# 0  c
# 1  d
# ----------
按照字典分组

 

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

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

df = pd.DataFrame({'a':[1,2,3,1],'b':['a','b','a','b'],'c':np.arange(3,7),'d':np.arange(2,6)})
print(df)
print(df.groupby('a').agg(['mean','sum']))  #b列为非数值,忽略
print(df.groupby('b').agg([np.sum,np.mean]))
#    a  b  c  d
# 0  1  a  3  2
# 1  2  b  4  3
# 2  3  a  5  4
# 3  1  b  6  5
#      c        d
#   mean sum mean sum
# a
# 1  4.5   9  3.5   7
# 2  4.0   4  3.0   3
# 3  5.0   5  4.0   4
#     a        c        d
#   sum mean sum mean sum mean
# b
# a   4  2.0   8    4   6    3
# b   3  1.5  10    5   8    4
分组后多函数计算agg

 

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

df = pd.DataFrame({'a':[1,2,3,1],'b':['a','b','a','b'],'c':np.arange(3,7),'d':np.arange(2,6)})
print(df.groupby('b')['c'].agg({'result_sum':np.sum,'result_mean':np.mean}))
#    result_sum  result_mean
# b                         
# a           8            4
# b          10            5
多函数计算后自定义列名称

 

 

二、transform

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

df = pd.DataFrame({'A':['zhao','li','wang','li','zhao'],'B':['one','one','two','two','three'],'C':np.arange(1,6),'D':np.arange(5,10)})
print(df)
print(df.groupby('B').mean())  #只包含one、two、three三行
print(df.groupby('B').transform(np.mean))  #结果为5行,B列内容相同的行的结果相同
#       A      B  C  D
# 0  zhao    one  1  5
# 1    li    one  2  6
# 2  wang    two  3  7
# 3    li    two  4  8
# 4  zhao  three  5  9
#          C    D
# B              
# one    1.5  5.5
# three  5.0  9.0
# two    3.5  7.5
#      C    D
# 0  1.5  5.5
# 1  1.5  5.5
# 2  3.5  7.5
# 3  3.5  7.5
# 4  5.0  9.0
transform()演示

 

 

三、applay

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

def func(df,n):return ***df.groupby('*').apply(func,n)#自定义函数func,第一个参数为pandas对象,并返回值
#分组后使用apply函数,将自定义函数的名称作为第一个参数,第二个参数传递给自定义函数的第二个参数

 

df = pd.DataFrame({'A':['zhao','li','wang','li','zhao','zhao'],'B':['one','one','two','two','three','two'],'C':np.arange(1,7),'D':np.arange(4,10)})
def f(d,n):return d.sort_index()[:n]  #按照索引排序,并返回前n行
print(df)
print(df.groupby('A').apply(f,2))  #按照A分组,对结果按索引排序,并返回每组的前n行
      A      B  C  D
# 0  zhao    one  1  4
# 1    li    one  2  5
# 2  wang    two  3  6
# 3    li    two  4  7
# 4  zhao  three  5  8
# 5  zhao    two  6  9
#            A      B  C  D
# A                        
# li   1    li    one  2  5
#      3    li    two  4  7
# wang 2  wang    two  3  6
# zhao 0  zhao    one  1  4
#      4  zhao  three  5  8
apply()自定义统计方法

 

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

pivot_table(self, values=None, index=None, columns=None, aggfunc='mean', 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
import numpy as np
import pandas as pd
date = ['2019/5/1','2019/5/2','2019/5/3']*3
df = pd.DataFrame({'date':pd.to_datetime(date),'key':list('abcbacbca'),'value':np.arange(1,10)})
print(df)
print(df.pivot_table(index='date',values='value',columns='key',aggfunc=np.sum))
print(df.pivot_table(index=['date','key'],values='value',aggfunc=np.sum))
#         date key  value
# 0 2019-05-01   a      1
# 1 2019-05-02   b      2
# 2 2019-05-03   c      3
# 3 2019-05-01   b      4
# 4 2019-05-02   a      5
# 5 2019-05-03   c      6
# 6 2019-05-01   b      7
# 7 2019-05-02   c      8
# 8 2019-05-03   a      9
# key           a     b    c
# date                      
# 2019-05-01  1.0  11.0  NaN
# 2019-05-02  5.0   2.0  8.0
# 2019-05-03  9.0   NaN  9.0
#                 value
# date       key       
# 2019-05-01 a        1
#            b       11
# 2019-05-02 a        5
#            b        2
#            c        8
# 2019-05-03 a        9
#            c        9
数据透视表pivot_table()

 

 

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

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

index 透视行

columns 透视列

values 对哪一列进行透视

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

 

五、交叉表crossta()

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

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的名称
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'])
print(pd.crosstab(df['A'],df['B']))   #表示统计A为1且B为1出现的次数,A为2且B为1出现的次数,A为4且B为1出现的次数……
# B    1  2  a
# A
# 1.0  0  1  0
# 2.0  0  0  1
# 4.0  1  0  0

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

 

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

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

 

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

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

 

margins增加行和列的总数统计

print(pd.crosstab(df['A'],df['B']))   
print(pd.crosstab(df['A'],df['B'],margins=True))
# B    1  2  a
# A
# 1.0  0  1  0
# 2.0  0  0  1
# 4.0  1  0  0# B    1  2  a  All
# A                
# 1.0  0  1  0    1
# 2.0  0  0  1    1
# 4.0  1  0  0    1
# All  1  1  1    3

 

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

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

 

转载于:https://www.cnblogs.com/Forever77/p/11288682.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/391916.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

js能否打印服务器端文档,js打印远程服务器文件

js打印远程服务器文件 内容精选换一换对于密码鉴权方式创建的Windows 2012弹性云服务器&#xff0c;使用初始密码以MSTSC方式登录时&#xff0c;登录失败&#xff0c;系统显示“第一次登录之前&#xff0c;你必须更改密码。请更新密码&#xff0c;或者与系统管理员或技术支持联…

spring—JdbcTemplate使用

JdbcTemplate基本使用 01-JdbcTemplate基本使用-概述(了解) JdbcTemplate是spring框架中提供的一个对象&#xff0c;是对原始繁琐的Jdbc API对象的简单封装。spring框架为我们提供了很多的操作模板类。例如&#xff1a;操作关系型数据的JdbcTemplate和HibernateTemplate&…

vanilla_如何在Vanilla JavaScript中操作DOM

vanillaby carlos da costa通过卡洛斯达科斯塔 如何在Vanilla JavaScript中操作DOM (How to manipulate the DOM in Vanilla JavaScript) So you have learned variables, selection structures, and loops. Now it is time to learn about DOM manipulation and to start doi…

NOIP201202寻宝

题目 试题描述传说很遥远的藏宝楼顶层藏着诱人的宝藏。 小明历尽千辛万苦终于找到传说中的这个藏宝楼&#xff0c;藏宝楼的门口竖着一个木板&#xff0c;上面写有几个大字&#xff1a;寻宝说明书。说明书的内容如下&#xff1a;藏宝楼共有N1层&#xff0c;最上面一层是顶层&…

修改UITextField中的placeholder的字体

修改字体颜色&#xff1a; [textField setValue:[UIColor redColor] forKeyPath:"_placeholderLabel.textColor"]; 复制代码 修改字体大小&#xff1a; [textField setValue:[UIFont boldSystemFontOfSize:16] forKeyPath:"_placeholderLabel.font"]; 复…

如何使用Python处理丢失的数据

The complete notebook and required datasets can be found in the git repo here完整的笔记本和所需的数据集可以在git repo中找到 Real-world data often has missing values.实际数据通常缺少值 。 Data can have missing values for a number of reasons such as observ…

MySQL—隔离级别

READ UNCOMMITED(读未提交) 即读取到了正在修改但是却还没有提交的数据&#xff0c;这就会造成数据读取的错误。 READ COMMITED(提交读/不可重复读) 它与READ UNCOMMITED的区别在于&#xff0c;它规定读取的时候读到的数据只能是提交后的数据。 这个级别所带来的问题就是不可…

做虚拟化服务器的配资一致嘛,服务器虚拟化技术在校园网管理中的应用探讨.pdf...

第 卷 第 期 江 苏 建 筑 职 业 技 术 学 院 学 报14 3 Vol.14 曧.3年 月 JOURNAL OF JIANGSU JIANZHU INSTITUTE2014 09 Se .2014p服务器虚拟化技术在校园网管理中的应用探讨,汪小霞 江建( , )健雄职业技术学院 软件与服务外包学院 江苏 太仓 215411: , ,摘 要 高校校园网数据…

aws中部署防火墙_如何在AWS中设置自动部署

aws中部署防火墙by Harry Sauers哈里绍尔斯(Harry Sauers) 如何在AWS中设置自动部署 (How to set up automated deployment in AWS) 设置和配置服务器 (Provisioning and Configuring Servers) 介绍 (Introduction) In this tutorial, you’ll learn how to use Amazon’s AWS…

Runtime的应用

来自&#xff1a;http://www.imlifengfeng.com/blog/?p397 1、快速归档 (id)initWithCoder:(NSCoder *)aDecoder { if (self [super init]) { unsigned int outCount; Ivar * ivars class_copyIvarList([self class], &outCount); for (int i 0; i < outCount; i ) …

使用 VisualVM 进行性能分析及调优

https://www.ibm.com/developerworks/cn/java/j-lo-visualvm/转载于:https://www.cnblogs.com/adolfmc/p/7238893.html

spring—事务控制

编程式事务控制相关对象 PlatformTransactionManager PlatformTransactionManager 接口是 spring 的事务管理器&#xff0c;它里面提供了我们常用的操作事务的方法。注意&#xff1a; PlatformTransactionManager 是接口类型&#xff0c;不同的 Dao 层技术则有不同的实现类 …

为什么印度盛产码农_印度农产品价格的时间序列分析

为什么印度盛产码农Agriculture is at the center of Indian economy and any major change in the sector leads to a multiplier effect on the entire economy. With around 17% contribution to the Gross Domestic Product (GDP), it provides employment to more than 50…

SAP NetWeaver

SAP的新一代企业级服务架构——NetWeaver    SAP NetWeaver是下一代基于服务的平台&#xff0c;它将作为未来所有SAP应用程序的基础。NetWeaver包含了一个门户框架&#xff0c;商业智能和报表&#xff0c;商业流程管理&#xff08;BPM&#xff09;&#xff0c;自主数据管理&a…

NotifyMyFrontEnd 函数背后的数据缓冲区(一)

async.c的 static void NotifyMyFrontEnd(const char *channel, const char *payload, int32 srcPid) 函数中的主要逻辑是这样的&#xff1a;复制代码if (whereToSendOutput DestRemote) { StringInfoData buf; pq_beginmessage(&buf, A); //cursor 为 A pq…

最后期限 软件工程_如何在软件开发的最后期限内实现和平

最后期限 软件工程D E A D L I N E…最后期限… As a developer, this is one of your biggest nightmares or should I say your enemy? Name it whatever you want.作为开发人员&#xff0c;这是您最大的噩梦之一&#xff0c;还是我应该说您的敌人&#xff1f; 随便命名。 …

SQL Server的复合索引学习【转载】

概要什么是单一索引,什么又是复合索引呢? 何时新建复合索引&#xff0c;复合索引又需要注意些什么呢&#xff1f;本篇文章主要是对网上一些讨论的总结。一.概念单一索引是指索引列为一列的情况,即新建索引的语句只实施在一列上。用户可以在多个列上建立索引&#xff0c;这种索…

leetcode 1423. 可获得的最大点数(滑动窗口)

几张卡牌 排成一行&#xff0c;每张卡牌都有一个对应的点数。点数由整数数组 cardPoints 给出。 每次行动&#xff0c;你可以从行的开头或者末尾拿一张卡牌&#xff0c;最终你必须正好拿 k 张卡牌。 你的点数就是你拿到手中的所有卡牌的点数之和。 给你一个整数数组 cardPoi…

pandas处理excel文件和csv文件

一、csv文件 csv以纯文本形式存储表格数据 pd.read_csv(文件名)&#xff0c;可添加参数enginepython,encodinggbk 一般来说&#xff0c;windows系统的默认编码为gbk&#xff0c;可在cmd窗口通过chcp查看活动页代码&#xff0c;936即代表gb2312。 例如我的电脑默认编码时gb2312&…

tukey检测_回到数据分析的未来:Tukey真空度的整洁实现

tukey检测One of John Tukey’s landmark papers, “The Future of Data Analysis”, contains a set of analytical techniques that have gone largely unnoticed, as if they’re hiding in plain sight.John Tukey的标志性论文之一&#xff0c;“ 数据分析的未来 ”&#x…