侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

python pandas模块基础学习详解

Python  /  管理员 发布于 7年前   328

Pandas类似R语言中的数据框(DataFrame),Pandas基于Numpy,但是对于数据框结构的处理比Numpy要来的容易。

1. Pandas的基本数据结构和使用

Pandas有两个主要的数据结构:Series和DataFrame。Series类似Numpy中的一维数组,DataFrame则是使用较多的多维表格数据结构。

Series的创建

>>>import numpy as np>>>import pandas as pd>>>s=pd.Series([1,2,3,np.nan,44,1]) # np.nan创建一个缺失数值>>>s # 若未指定,Series会自动建立index,此处自动建立索引0-50   1.01   2.02   3.03   NaN4  44.05   1.0dtype: float64

DataFrame的创建

>>>dates=pd.date_range('20170101',periods=6)>>>datesDatetimeIndex(['2017-01-01', '2017-01-02', '2017-01-03', '2017-01-04',        '2017-01-05', '2017-01-06'],       dtype='datetime64[ns]', freq='D')>>>df=pd.DataFrame(np.random.randn(6,4),index=dates,columns=['a','b','c','d'])>>>df           a     b     c     d2017-01-01 -1.993447 1.272175 -1.578337 -1.9725262017-01-02 0.092701 -0.503654 -0.540655 -0.1263862017-01-03 0.191769 -0.578872 -1.693449 0.4578912017-01-04 2.121120 0.521884 -0.419368 -1.9165852017-01-05 1.642063 0.222134 0.108531 -1.8589062017-01-06 0.636639 0.487491 0.617841 -1.597920

DataFrame可以跟Numpy一样根据索引取出其中的数据,只是DataFrame索引方式更加多样化。DataFrame不仅可以根据默认的行列编号来索引,还可以根据标签序列来索引。

还可以采用字典的方式创建DataFrame:

>>>df2=pd.DataFrame({'a':1,'b':'hello kitty','c':np.arange(2),'d':['o','k']})>>>df2   a      b c d0 1 hello kitty 0 o1 1 hello kitty 1 k

对于DataFrame的一些属性也可以采用相应的方法查看

dtype # 查看数据类型index # 查看行序列或者索引columns # 查看各列的标签values # 查看数据框内的数据,也即不含表头索引的数据describe # 查看数据的一些信息,如每一列的极值,均值,中位数之类的,只能对数值型数据统计信息transpose # 转置,也可用T来操作sort_index # 排序,可按行或列index排序输出sort_values # 按数据值来排序

一些例子

>>>df2.dtypesa   int64b  objectc   int64d  objectdtype: object>>>df2.indexRangeIndex(start=0, stop=2, step=1)>>>df2.columnsIndex(['a', 'b', 'c', 'd'], dtype='object')>>>df2.valuesarray([[1, 'hello kitty', 0, 'o'],    [1, 'hello kitty', 1, 'k']], dtype=object)>>>df2.describe # 只能对数值型数据统计信息     a     ccount 2.0 2.000000mean  1.0 0.500000std  0.0 0.707107min  1.0 0.00000025%  1.0 0.25000050%  1.0 0.50000075%  1.0 0.750000max  1.0 1.000000>>>df2.T       0      1a      1      1b hello kitty hello kittyc      0      1d      o      k>>>df2.sort_index(axis=1,ascending=False) # axis=1 按列标签从大到小排列   d c      b a0 o 0 hello kitty 11 k 1 hello kitty 1>>>df2.sort_index(axis=0,ascending=False) # 按行标签从大到小排序   a      b c d1 1 hello kitty 1 k0 1 hello kitty 0 o>>>df2.sort_values(by="c",ascending=False) # 按c列的值从大到小排序   a      b c d1 1 hello kitty 1 k0 1 hello kitty 0 o

2. 从DataFrame中筛选取出目的数据

从DataFrame中取出目的数据方法有多种,一般常用的有:

  •  - 直接根据索引选取
  •  - 根据标签选取(纵向选择列):loc
  •  - 根据序列(横向选择行): iloc
  •  - 组合使用标签序列来选取特定位置的数据: ix
  •  - 通过逻辑判断筛选

简单选取

>>>import numpy as np>>>import pandas as pd>>>dates=pd.date_range('20170101',periods=6)>>>df=pd.DataFrame(np.arange(24).reshape((6,4)),index=dates,columns=['a','b','c','d'])>>>df        a  b  c  d2017-01-01  0  1  2  32017-01-02  4  5  6  72017-01-03  8  9 10 112017-01-04 12 13 14 152017-01-05 16 17 18 192017-01-06 20 21 22 23>>>df['a']     # 根据表签直接选取a列,也可用df.a,结果相同2017-01-01   02017-01-02   42017-01-03   82017-01-04  122017-01-05  162017-01-06  20Freq: D, Name: a, dtype: int64>>>df[0:3]  # 选择前3行,也可用行标签 df['2017-01-01':'2017-01-03'],结果相同,但是无法用此法选择多列       a b  c  d2017-01-01 0 1  2  32017-01-02 4 5  6  72017-01-03 8 9 10 11

loc使用显式的行标签来选取数据

DataFrame行的表示方式有两种,一种是通过显式的行标签来索引,另一种是通过默认隐式的行号来索引。loc方法是通过行标签来索引选取目标行,可以配合列标签来选取特定位置的数据。

>>>df.loc['2017-01-01':'2017-01-03']       a b  c  d2017-01-01 0 1  2  32017-01-02 4 5  6  72017-01-03 8 9 10 11>>>df.loc['2017-01-01',['a','b']]  # 选取特定行的a,b列a  0b  1Name: 2017-01-01 00:00:00, dtype: int64

iloc使用隐式的行序列号来选取数据

使用iloc可以搭配列序列号来更简单的选取特定位点的数据

>>>df.iloc[3,1]13>>>df.iloc[1:3,2:4]        c  d2017-01-02  6  72017-01-03 10 11

ix利用ix可以混用显式标签与隐式序列号

loc只能使用显式标签来选取数据,而iloc只能使用隐式序列号来选取数据,ix则能将二者结合起来使用。

>>> df.ix[3:5,['a','b']]       a  b2017-01-04 12 132017-01-05 16 17

使用逻辑判断来选取数据

>>>df        a  b  c  d2017-01-01  0  1  2  32017-01-02  4  5  6  72017-01-03  8  9 10 112017-01-04 12 13 14 152017-01-05 16 17 18 192017-01-06 20 21 22 23>>>df[df['a']>5] # 等价于df[df.a>5]        a  b  c  d2017-01-03  8  9 10 112017-01-04 12 13 14 152017-01-05 16 17 18 192017-01-06 20 21 22 23

3. Pandas设置特定位置值

>>>import numpy as np>>>import pandas as pd>>>dates=pd.date_range('20170101',periods=6)>>>datas=np.arange(24).reshape((6,4))>>>columns=['a','b','c','d']>>>df=pd.DataFra me(data=datas,index=dates,colums=columns)>>>df.iloc[2,2:4]=111 # 将第2行2,3列位置的数据改为111        a  b  c  d2017-01-01  0  1  2  32017-01-02  4  5  6  72017-01-03  8  9 111 1112017-01-04 12 13  14  152017-01-05 16 17  18  192017-01-06 20 21  22  23>>>df.b[df['a']>10]=0 # 等价于df.b[df.a>10] # 以a列大于10的数的位置为参考,改变b列相应行的数值为0        a b  c  d2017-01-01  0 1  2  32017-01-02  4 5  6  72017-01-03  8 9 111 1112017-01-04 12 0  14  152017-01-05 16 0  18  192017-01-06 20 0  22  23>>>df['f']=np.nan  # 新建f列并设置数值为np.nan       a b  c  d  f2017-01-01  0 1  2  3 NaN2017-01-02  4 5  6  7 NaN2017-01-03  8 9 111 111 NaN2017-01-04 12 0  14  15 NaN2017-01-05 16 0  18  19 NaN2017-01-06 20 0  22  23 NaN>>># 用上面的方法也可以加上`Series`序列,但是必须与列长度一致>>>df['e']=pd.Series(np.arange(6),index=dates)>>>df       a b  c  d  f e2017-01-01  0 1  2  3 NaN 02017-01-02  4 5  6  7 NaN 12017-01-03  8 9 111 111 NaN 22017-01-04 12 0  14  15 NaN 32017-01-05 16 0  18  19 NaN 42017-01-06 20 0  22  23 NaN 5

4. 处理丢失数据

有时候我们的数据中会有一些空的或者缺失(NaN)数据,使用dropna可以选择性的删除或填补这些NaN数据。drop函数可以选择性的删除行或者列,drop_duplicates去除冗余。fillna则将NaN值用其他值替换。操作后不改变原值,若要保存更改需重新赋值。

>>>import numpy as np>>>import pandas as pd>>>df=pd.DataFrame(np.arange(24).reshape(6,4),index=pd.date_range('20170101',periods=6),columns=['a','b','c','d'])>>>df       a  b  c  d2017-01-01  0  1  2  32017-01-02  4  5  6  72017-01-03  8  9 10 112017-01-04 12 13 14 152017-01-05 16 17 18 192017-01-06 20 21 22 23>>>df.iloc[1,3]=np.nan>>>di.iloc[3,2]=np.nan>>>df.       a  b   c   d2017-01-01  0  1  2.0  3.02017-01-02  4  5  6.0  NaN2017-01-03  8  9 10.0 11.02017-01-04 12 13  NaN 15.02017-01-05 16 17 18.0 19.02017-01-06 20 21 22.0 23.0>>>df.dropna(axis=0,how='any') # axis=0(1)表示将含有NaN的行(列)删除。   # how='any'表示只要行(或列,视axis取值而定)含有NaN则将该行(列)删除,   # how='all'表示当某行(列)全部为NaN时才删除       a  b   c   d2017-01-01  0  1  2.0  3.02017-01-03  8  9 10.0 11.02017-01-05 16 17 18.0 19.02017-01-06 20 21 22.0 23.0>>>df.fillna(value=55)       a  b   c   d2017-01-01  0  1  2.0  3.02017-01-02  4  5  6.0 55.02017-01-03  8  9 10.0 11.02017-01-04 12 13 55.0 15.02017-01-05 16 17 18.0 19.02017-01-06 20 21 22.0 23.0

还可以利用函数来检查数据中是否有或者全部为NaN

>>>np.any(df.isnull())==TrueTrue>>>np.all(df.isnull())==TrueFalse

5. 数据的导入以及导出

一般excel文件以csv方式读入,pd.read_csv(file),data保存为filedata.to_csv(file)。

6. 数据添加合并

本节主要学习Pandas的一些简单基本的数据添加合并方法:concat,append。

concat合并方式类似于Numpy的concatenate方法,可横向或者竖向合并。

>>>import numpy as np>>>import pandas as pd>>> df1=pd.DataFrame(np.ones((3,4))*0,columns=['a','b','c','d'])>>> df2=pd.DataFrame(np.ones((3,4))*1,columns=['a','b','c','d'])>>> df3=pd.DataFrame(np.ones((3,4))*2,columns=['a','b','c','d'])>>>res=pd.concat([df1,df2,df3],axis=0) # axis=0表示按行堆叠合并,axis=1表示按列左右合并>>>res    a  b  c  d0 0.0 0.0 0.0 0.01 0.0 0.0 0.0 0.02 0.0 0.0 0.0 0.00 1.0 1.0 1.0 1.01 1.0 1.0 1.0 1.02 1.0 1.0 1.0 1.00 2.0 2.0 2.0 2.01 2.0 2.0 2.0 2.02 2.0 2.0 2.0 2.0>>># 使用ignore_index=True参数可以重置行标签>>>res=pd.concat([df1,df2,df3],axis=0,ignore_index=True)>>>res    a  b  c  d0 0.0 0.0 0.0 0.01 0.0 0.0 0.0 0.02 0.0 0.0 0.0 0.03 1.0 1.0 1.0 1.04 1.0 1.0 1.0 1.05 1.0 1.0 1.0 1.06 2.0 2.0 2.0 2.07 2.0 2.0 2.0 2.08 2.0 2.0 2.0 2.0

join参数提供了更多样化的合并方式。join=outer为默认值,表示将几个合并的数据都用上,具有相同列标签的合二为一,上下合并,不同列标签的独自成列,原来没有数值的位置以NaN填充;join=inner则只将具有相同列标签的(行)列上下合并,其余的列舍弃。简言之,outer代表并集,inner代表交集**。

>>>import numpy as np>>>import pandas as pd>>>df1=pd.DataFrame(np.ones((3,4)),index=[1,2,3],columns=['a','b','c','d'])>>>df2=pd.DataFrame(np.ones((3,4))*2,index=[1,2,3],columns=['b','c','d','e'])>>>res=pd.concat([df1,df2],axis=0,join='outer')>>>res    a  b  c  d  e1 1.0 1.0 1.0 1.0 NaN2 1.0 1.0 1.0 1.0 NaN3 1.0 1.0 1.0 1.0 NaN1 NaN 2.0 2.0 2.0 2.02 NaN 2.0 2.0 2.0 2.03 NaN 2.0 2.0 2.0 2.0>>>res1=pd.concat([df1,df2],axis=1,join='outer')  # axis=1表示按列左右合并具有相同的行标签的,其余的各成一行,NaN补齐空缺>>>res1    a  b  c  d  b  c  d  e1 1.0 1.0 1.0 1.0 2.0 2.0 2.0 2.02 1.0 1.0 1.0 1.0 2.0 2.0 2.0 2.03 1.0 1.0 1.0 1.0 2.0 2.0 2.0 2.0>>>res2=pd.concat([df1,df2],axis=0,join='inner',ignore_index=True) # 将具有相同列标签的列上下合并>>>res2   b  c  d0 1.0 1.0 1.01 1.0 1.0 1.02 1.0 1.0 1.03 2.0 2.0 2.04 2.0 2.0 2.05 2.0 2.0 2.0

join_axes参数可以设定参考系,以设定的参考来合并,参考系中没有的舍弃掉

>>>import numpy as np>>>import pandas as pd>>>df1=pd.DataFrame(np.ones((3,4)),index=[1,2,3],columns=['a','b','c','d'])>>> df2=pd.DataFrame(np.ones((3,4))*2,index=[2,3,4],columns=['b','c','d','e'])>>>res3=pd.concat([df1,df2],axis=0,join_axes=[df1.columns])# 以df1的列标签为参考上下合并拥有相同列标签的列>>>res3    a  b  c  d1 1.0 1.0 1.0 1.02 1.0 1.0 1.0 1.03 1.0 1.0 1.0 1.02 NaN 2.0 2.0 2.03 NaN 2.0 2.0 2.04 NaN 2.0 2.0 2.0>>>res4=pd.concat([df1,df2],axis=1,join_axes=[df1.index])# 以df1行标签为参考,左右合并拥有相同行标签的各列    a  b  c  d  b  c  d  e1 1.0 1.0 1.0 1.0 NaN NaN NaN NaN2 1.0 1.0 1.0 1.0 2.0 2.0 2.0 2.03 1.0 1.0 1.0 1.0 2.0 2.0 2.0 2.0

append只有上下合并,没有左右合并

>>>df1=pd.DataFrame(np.ones((3,4)),index=[1,2,3],columns=['a','b','c','d'])>>> df2=pd.DataFrame(np.ones((3,4))*2,index=[2,3,4],columns=['b','c','d','e'])>>>res5=df1.append(df2,ignore_index=True)>>>res5    a  b  c  d  e0 1.0 1.0 1.0 1.0 NaN1 1.0 1.0 1.0 1.0 NaN2 1.0 1.0 1.0 1.0 NaN3 NaN 2.0 2.0 2.0 2.04 NaN 2.0 2.0 2.0 2.05 NaN 2.0 2.0 2.0 2.0

7. Pandas高级合并:merge

merge合并与concat类似,只是merge可以通过一个或多个键将两个数据集的行连接起来。

merge(left, right, how='inner', on=None, left_on=None, right_on=None, left_index=False, right_index=False, sort=False, suffixes=('_x', '_y'), copy=True, indicator=False)

参数说明:

  • left与right:两个不同的DataFrame
  • how:指的是合并(连接)的方式有inner(内连接),left(左外连接),right(右外连接),outer(全外连接);默认为inner
  • on : 指的是用于连接的列索引名称。必须存在右右两个DataFrame对象中,如果没有指定且其他参数也未指定则以两个DataFrame的列名交集做为连接键
  • left_on:左侧DataFrame中用作连接键的列名;这个参数中左右列名不相同,但代表的含义相同时非常有用。
  • right_on:右侧DataFrame中用作 连接键的列名
  • left_index:使用左侧DataFrame中的行索引做为连接键
  • right_index:使用右侧DataFrame中的行索引做为连接键
  • sort:默认为True,将合并的数据进行排序。在大多数情况下设置为False可以提高性能
  • suffixes:字符串值组成的元组,用于指定当左右DataFrame存在相同列名时在列名后面附加的后缀名称,默认为('_x','_y')
  • copy:默认为True,总是将数据复制到数据结构中;大多数情况下设置为False可以提高性能
  • indicator:显示合并数据中来源情况;如只来自己于左边(left_only)、两者(both)
>>>import pandas as pd>>>df1=pd.DataFrame({'key':['k0','k1','k2','k3'],'A':['a0','a1','a2','a3'],'B':['b0','b1','b2','b3']})>>>df2=pd.DataFrame({'key':['k0','k1','k2','k3'],'C':['c0','c1','c2','c3'],'D':['d0','d1','d2','d3']})>>> res=pd.merge(df1,df2,on='key',indicator=True)>>>res  A  B key  C  D _merge0 a0 b0 k0 c0 d0  both1 a1 b1 k1 c1 d1  both2 a2 b2 k2 c2 d2  both3 a3 b3 k3 c3 d3  both

依据行index合并与依据列key合并用法类似

>>>res2=pd.merge(df1,df2,left_index=True,right_index=True,indicator=True)>>>res2  A  B key_x  C  D key_y _merge0 a0 b0  k0 c0 d0  k0  both1 a1 b1  k1 c1 d1  k1  both2 a2 b2  k2 c2 d2  k2  both3 a3 b3  k3 c3 d3  k3  both

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


  • 上一条:
    Python实现个人微信号自动监控告警的示例
    下一条:
    python将excel转换为csv的代码方法总结
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在python语言中Flask框架的学习及简单功能示例(0个评论)
    • 在Python语言中实现GUI全屏倒计时代码示例(0个评论)
    • Python + zipfile库实现zip文件解压自动化脚本示例(0个评论)
    • python爬虫BeautifulSoup快速抓取网站图片(1个评论)
    • vscode 配置 python3开发环境的方法(0个评论)
    • 近期文章
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • PHP 8.4 Alpha 1现已发布!(0个评论)
    • Laravel 11.15版本发布 - Eloquent Builder中添加的泛型(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2018-04
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2022-01
    • 2023-07
    • 2023-10
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客