pandas模块常用函数解析之DataFrame

pandas模块常用函数解析之DataFrame

以下命令都是在浏览器中输入。

cmd命令窗口输入:jupyter notebook

打开浏览器输入网址http://localhost:8888/

一、导入模块

import numpy as np
import pandas as pd
from pandas import Series,DataFrame

二、DataFrame

DataFrame是一个【表格型】的数据结构。DataFrame由按一定顺序排列的多列数据组成。设计初衷是将Series的使用场景从一维拓展到多维。DataFrame既有行索引,也有列索引。

  • 行索引:index
  • 列索引:columns
  • 值:values

1、 DataFrame的创建

1.1 使用ndarray创建DataFrame
DataFrame(data=np.random.randint(60,100,size=(2,3)),
         index=['期中','期末'],
         columns=['张三','李四','王老五'])

这里写图片描述

1.2 使用字典创建

最常用的方法是传递一个字典来创建。DataFrame以字典的键作为每一【列】的名称,以字典的值(一个数组)作为每一列。

此外,DataFrame会自动加上每一行的索引。

使用字典创建的DataFrame后,则columns参数将不可被使用。

同Series一样,若传入的列与字典的键不匹配,则相应的值为NaN。

dic={

    '期中':[50,60,70],
    '期末':[80,90,89]
}
#使用字典创建一个DataFrame
df=DataFrame(data=dic,index=['张三','李四','王老五'])
df

这里写图片描述

1.3 DataFrame属性:values、columns、index、shape

这里写图片描述

2、 DataFrame的索引

2.1 对列进行索引
  • 通过类似字典的方式 df[‘q’]
  • 通过属性的方式 df.q

可以将DataFrame的列获取为一个Series。返回的Series拥有原DataFrame相同的索引,且name属性也已经设置好了,就是相应的列名。

#修改列索引
df.columns=['qizhong','qimo']
df

这里写图片描述

df['qizhong]
df.qizhong
df[['qizhong','qimo']]

这里写图片描述

2.2 对行进行索引
  • 使用.loc[]加index来进行行索引
  • 使用.iloc[]加整数来进行行索引
    同样返回一个Series,index为原来的columns。
df.loc['李四']

这里写图片描述

df.iloc[1]

这里写图片描述

2.3 对元素进行索引的方法
  • 使用列索引
  • 使用行索引(iloc[3,1] or loc[‘C’,’q’]) 行索引在前,列索引在后
df.loc['王老五','qimo']

这里写图片描述

3、切片

使用冒号进行切片。

3.1 使用中括号
df['张三':'李四']

这里写图片描述

3.2 使用loc和iloc中

如: df.loc[‘B’:’C’,’丙’:’丁’]

df.loc[:'李四','qizhong':'qimo']  #结合numpy中的二维数组理解

这里写图片描述

注意】 直接用中括号时:

  • 索引表示的是列索引
  • 切片表示的是行切片

4、 DataFrame的运算

DataFrame之间的运算

同Series一样:

  • 在运算中自动对齐不同索引的数据
  • 如果索引不对应,则补NaN
4.1 DataFrame之间的运算
df1=df.copy()  #创建df的一个副本

这里写图片描述

df1.loc['jay']=[99,88]  #给df1添加一行
df1

这里写图片描述

df1['AAA']=[1,2,3,4]  #给df1添加一列
df1

这里写图片描述

df+df1

这里写图片描述

下面是Python 操作符与pandas操作函数的对应表:

Python Operator Pandas Method(s)
+ add()
- sub(), subtract()
* mul(), multiply()
/ truediv(), div(), divide()
// floordiv()
% mod()
** pow()

三、处理丢失数据

有两种丢失数据类型:

  • None
  • np.nan(NaN)

1. None

None是Python自带的,其类型为python object。因此,None不能参与到任何计算中。

#查看None的数据类型
type(None)
结果为:
NoneType

2. np.nan(NaN)

np.nan是浮点类型,能参与到计算中。但计算的结果总是NaN。

type(np.nan)
结果为:
float
np.nan+10
结果为:
nan

object类型的运算要比int类型的运算慢得多

计算不同数据类型求和时间

%timeit np.arange(1e5,dtype=object).sum()
%timeit np.arange(1e5,dtype=float).sum()

这里写图片描述
object:运行时间的8.09ms;
float:运行时间是3.159us,可看出使用object做运算,很耗时。

3. pandas中的None与NaN

3.1 pandas中None与np.nan都视作np.nan

在pandas中,None和np.nan统一处理成NAN,numpy并不处理。

处理成NaN,float型,可用于计算,计算结果为NaN.

3.2 pandas处理空值操作
  • isnull()如果为NaN就返回True,否则返回False
  • notnull() 如果为NaN就返回False,否则返回True
  • dropna(): 过滤丢失数据(NaN)
  • fillna(): 填充丢失数据(NaN)
#创建DataFrame,给其中某些元素赋值为nan
df=DataFrame(np.random.randint(1,100,size=(4,6)),
            index=['A','B','C','D'],
            columns=['a','b','c','d','e','f'])
df

这里写图片描述

#将空值赋值给df中的某些元素
df.loc['A','c']=np.nan
df.loc['C','c']=None
df.loc['B','d']=None
df

这里写图片描述

(1)判断函数

  • isnull()
  • notnull()

这里写图片描述
这里写图片描述

(2)df.notnull().any()/all()

#.any()相当于“或”,只要有一个为True,结果就为True
df.notnull().any() #axis=0,列

这里写图片描述
判断哪些行中存在空值

#.all()相当于"与",只要有一个为False,结果就为False
df.notnull().all(axis=1)

这里写图片描述
结果说明只有D行没有空值。

过滤空值:

#1.判断哪些行中存在空值
condition=df.notnull().all(axis=1)
#2.过滤空值
#df.loc[[True,True,True,False]]
df.loc[condition]

这里写图片描述

df.dropna() 可以选择过滤的是行还是列(默认为行):axis中0表示行,1表示的列 。

过滤带空值的列
df.dropna(axis=1)

这里写图片描述

how参数:有两个值’all’表示是所有为空值才过滤;’any’表示有一个为空值就过滤。

默认为’any’,一般使用’any’。

这里写图片描述

3.3 填充函数

适用于 Series和DataFrame 。

fillna():value和method参数。

value参数表示的是给NAN填充的数据值:

df.fillna(value=0)

这里写图片描述

method 控制填充的方式 有4种选择,常用(bfill和ffill) 前向填充还是后向填充 。

#向前填充,NaN的值用行前面的值代替
#axis=0,则用列前面的值代替
#如果前面没有值,则还是NaN
df.fillna(method='ffill',axis=1) 

这里写图片描述

limit 参数:控制填充的次数

df.loc['B','c']=None
df

这里写图片描述

#向后填充,列后面的值代替NaN,只填充2次
df.fillna(method='bfill',axis=0,limit=2) 

这里写图片描述

四、创建多层列索引

#导入库
import numpy as np
import pandas as pd 
from pandas import Series,DataFrame

1、隐式构造

最常见的方法是给DataFrame构造函数的index或者columns参数传递两个或更多的数组

DataFrame(data=np.random.randint(60,120,size=(2,4)),
         columns=[['qizhong','qizhong','qimo','qimo'],
                  ['chinese','math','chinese','math']],
         index=['tom','jay'])

这里写图片描述

2、显示构造pd.MultiIndex.from_

2.1 使用数组
#创建了一个索引对象,该索引对象为二层索引
col=pd.MultiIndex.from_arrays([['qizhong','qizhong','qimo','qimo'],
                           ['chinese','math','chinese','math']])
#创建DF对象
DataFrame(data=np.random.randint(60,120,size=(2,4)),index=['tom','jay'],
         columns=col)

这里写图片描述

2.2 使用tuple (元组)
#构建索引对象
col=pd.MultiIndex.from_tuples((('qizhong','chinese'),
                               ('qizhong','math'),
                               ('qimo','chinese'),
                               ('qimo','math')))
#创建DF对象
DataFrame(data=np.random.randint(60,120,size=(2,4)),
         index=['tom','jay'],
         columns=col)

这里写图片描述

2.3 使用product

最简单,推荐使用

#长江映射关系
col=pd.MultiIndex.from_product([['qizhong','qimo'],
                                ['chinese','math']])
#创建DF对象
DataFrame(data=np.random.randint(60,120,size=(2,4)),
          index=['tom','jay'],
          columns=col)

这里写图片描述

五、创建多层行索引

除了行索引index,列索引columns也能用同样的方法创建多层索引

index=pd.MultiIndex.from_product([['qizhong','qimo'],
                                ['chinese','math']])
df=DataFrame(data=np.random.randint(60,120,size=(4,2)),
            index=index,
            columns=['tom','jay'])
df

这里写图片描述

六、多层索引对象的索引与切片操作

1、 Series的操作

  • Series也会存在多级索引操作
s=Series(index=[['一级','一级','一级','二级','二级','二级'],
                ['A','B','C','D','E','F']],
         data=[11,22,33,44,55,66])
s

这里写图片描述

1.1 索引

【重要】对于Series来说,直接中括号[]与使用.loc()完全一样,

推荐使用.loc[]索引和切片。

不能跨级(索引级别:一级索引,二级索引)操作。

这里写图片描述

s.loc['一级']

这里写图片描述

1.2 切片

通过冒号进行切片

这里写图片描述

2、 DataFrame的操作

2.1 使用列名称来进行列索引
df['tom']['qizhong']

这里写图片描述

2.2 使用行名称来进行行索引

使用行索引需要用ix[]==iloc[],loc[]

【极其重要】推荐使用loc()函数

df.loc['qimo'].loc['math']

这里写图片描述

df.ix[0]   #与df.iloc[0]效果一样

这里写图片描述

2.3 切片
#行切片
df.loc['qizhong']['chinese':]

这里写图片描述

#列切片
df.loc[:,'tom':'jay']

这里写图片描述

 总结:
访问一列或多列 直接用中括号[columnname] 
                如: [[columname1,columnname2...]]
访问一行或多行  .loc[indexname]
访问某一个元素  .loc[indexname,columnname]  
行切片          .loc[index1:index2]        
列切片          .loc[:,column1:column2]    

七、索引的堆(stack)

对矩阵的索引进行变换处理

  • stack():把列索引变成行索引 (从上到左)
  • unstack():把行索引变成列索引(从左到上)

1、 stack()

删除列

#axis=1表示删除行,axis=0表示删除列
df.drop(['jarry'],axis=1,inplace=True)
df

这里写图片描述

#
df.stack()

这里写图片描述

2、 unstack()

df.unstack()

这里写图片描述

3、level参数

stack()和unstack()都有一个参数level,表示是把哪一级索引进行变换。

df.unstack(level=0)

这里写图片描述

【小技巧】使用stack()的时候,level等于哪一个,哪一个就消失,出现在行里。

【小技巧】使用unstack()的时候,level等于哪一个,哪一个就消失,出现在列里。

八、聚合操作

所谓的聚合操作:平均数,方差,最大值,最小值……

df.mean()

这里写图片描述

df.std(axis=0)  #方差

这里写图片描述

下面是Python 操作符与pandas操作函数的对应表:

Python Operator Pandas Method(s)
+ add()
- sub(), subtract()
* mul(), multiply()
/ truediv(), div(), divide()
// floordiv()
% mod()
** pow()

九、pandas的拼接操作

pandas的拼接分为两种:

  • 级联:pd.concat, pd.append
  • 合并:pd.merge, pd.join

1、级联

1.1 使用pd.concat()级联
#创建两个3*3的矩阵
df1=DataFrame(np.random.randint(0,100,size=(3,3)),
             index=['A','B','C'],columns=['a','b','c'])
df2=DataFrame(np.random.randint(0,100,size=(3,3)),
             index=['A','B','D'],columns=['a','b','d'])

这里写图片描述

pandas使用pd.concat函数进行级联,与np.concatenate函数类似,只是多了一些参数:

objs
axis=0
keys
join='outer' / 'inner':表示的是级联的方式,
        outer会将所有的项进行级联(忽略匹配和不匹配),
        而inner只会将匹配的项级联到一起,不匹配的不级联
ignore_index=False
pd.concat([df1,df2],axis=0)  #axis=0表示以列连接列的方式级联

这里写图片描述

pd.concat([df1,df2],axis=1) #axis=1表示以行连接行的方式级联

这里写图片描述

#keys可以用来增加多级索引,标记出原先的表
pd.concat([df1,df2],axis=1,keys=['df1','df2'])  

这里写图片描述

1.2 不匹配级联

不匹配指的是级联的维度的索引不一致。例如纵向级联时列索引不一致,横向级联时行索引不一致

有2种连接方式:

  • 外连接:补NaN(默认模式)
  • 内连接:只连接匹配的项
#join默认为'outer',当join='inner'时表示不匹配的将不级联
pd.concat([df1,df2],axis=1,
            keys=['df1+++','df2+++'],join='inner')

这里写图片描述

不同行不同列的两个矩阵进行级联

df3=DataFrame(np.random.randint(0,100,size=(4,4)),
             index=['A','B','C','D'],
             columns=['a','b','c','d'])
df4=DataFrame(np.random.randint(0,100,size=(3,3)),
             index=['A','B','D'],
             columns=['a','b','d'])

这里写图片描述

pd.concat([df3,df4])

这里写图片描述

1.3 使用df.append()函数添加

由于在后面级联的使用非常普遍,因此有一个函数append专门用于在后面添加 :

df1.append(df2) #相当于pd.concat([df1,df2],axis=0)

这里写图片描述

这里写图片描述

2、合并

使用pd.merge()合并

merge与concat的区别在于,merge需要依据某一共同的行或列来进行合并

使用pd.merge()合并时,会自动根据两者相同column名称的那一列,作为key来进行合并。

注意每一列元素的顺序不要求一致

参数:

  • how:outer取并集, inner取交集,left:左合并(包含左表的所有数据,不一定包含右表的所有数据),right:右合并(跟左合并相反)
  • on:当有多列相同的时候,可以使用on来指定使用那一列进行合并,on的值为一个列表
2.1 一对一合并
#创建df1
df1 = DataFrame({'employee':['Bob','Jake','Lisa'],
                'group':['Accounting','Engineering',
                        'Engineering'],
                })
df1

这里写图片描述

#创建df2
df2 = DataFrame({'employee':['Lisa','Bob','Jake'],
                'hire_date':[2004,2008,2012],
                })
df2

这里写图片描述

#merge()会自动把df1和df2中的‘employee’合并
pd.merge(df1,df2)

这里写图片描述

2.2 多对一合并
df3 = DataFrame({
    'employee':['Lisa','Jake'],
    'group':['Accounting','Engineering'],
    'hire_date':[2004,2016]})
df3

这里写图片描述

df4 = DataFrame({'group':['Accounting','Engineering',
                        'Engineering'],
                 'supervisor':['Carly','Guido','Steve']
                })
df4

这里写图片描述

pd.merge(df3,df4,how='outer')

这里写图片描述

2.3 多对多合并
df1 = DataFrame({'employee':['Bob','Jake','Lisa'],
                 'group':['Accounting','Engineering',
                         'Engineering']})
df1

这里写图片描述

df2=DataFrame({'group':['Engineering','Engineering','HR'],
                'supervisor':['Carly','Guido','Steve']
                })
df2

这里写图片描述

pd.merge(df1,df2,how='outer')

这里写图片描述

2.4 加载Excel、CSV表格数据
  • 加载excel数据:pd.read_excel(‘excel_path’,sheetname=1)

    参数excel_path为Excel文件绝对路径,sheetname为第几个表格(下标从0开始)

  • 加载csv数据:pd.csv(‘csv_path’)

df1=pd.read_excel('../data.xlsx',sheetname=1)
df1

这里写图片描述

2.5 key的规范化
  • 使用on=显式指定哪一列为key,当有多个key相同时使用
df1 = DataFrame({'employee':['Jack',"Summer","Steve"],
                 'group':['Accounting','Finance',
                         'Marketing']})
df1

这里写图片描述

df2 = DataFrame({'employee':['Jack','Bob',"Jake"],
                 'hire_date':[2003,2009,2012],
                'group':['Accounting','sell','ceo']})
df2

这里写图片描述

pd.merge(df1,df2,how='outer',on=['group','employee'])

这里写图片描述

  • 当两张表没有可进行连接的列时,可使用left_on和right_on手动指定merge中左右两边的哪一列作为连接的列
df1 = DataFrame({'employee':['Bobs','Linda','Bill'],
                'group':['Accounting','Product',
                        'Marketing'],
               'hire_date':[1998,2017,2018]})
df1

这里写图片描述

df5 = DataFrame({'name':['Lisa','Bobs','Bill'],
                'hire_dates':[1998,2016,2007]})
df5

这里写图片描述

pd.merge(df1,df5,left_on='hire_date',right_on='hire_dates',
        how='outer')

这里写图片描述

2.6 内合并\外合并\左合并\右合并

how参数={‘inner’,’outer’,’left’,’right’}

  • 内合并:只保留两者都有的key(默认模式),how=’inner’
df6 = DataFrame({'name':['Peter','Paul','Mary'],
               'food':['fish','beans','bread']}
               )
df6

这里写图片描述

df7 = DataFrame({'name':['Mary','Joseph'],
                'drink':['wine','beer']})
df7

这里写图片描述

pd.merge(df6,df7,how='inner')

这里写图片描述

  • 外合并 how=’outer’:补NaN
pd.merge(df6,df7,how='outer')

这里写图片描述

  • 左合并:保留左表全部数据,how=’left’
pd.merge(df6,df7,how='left')

这里写图片描述

  • 右合并:保留右表全部数据,how=’right’
pd.merge(df6,df7,how='right')

这里写图片描述

2.7 列冲突的解决

当列冲突时,即有多个列名称相同时,需要使用on=来指定哪一个列作为key,配合suffixes指定冲突列名。

可以使用suffixes=自己指定后缀。

df8 = DataFrame({'name':['Peter','Paul','Mary'],
                'rank':[1,2,3]})
df8

这里写图片描述

df9 = DataFrame({'name':['Peter','Paul','Mary'],
                'rank':[5,6,7]})
df9

这里写图片描述

#默认添加_x,_y
pd.merge(df8,df9,on='name')

这里写图片描述

#指定添加'_L','_R'
pd.merge(df8,df9,on = 'name',suffixes=['_L','_R'])

这里写图片描述

猜你喜欢

转载自blog.csdn.net/lm_is_dc/article/details/81114088