Python之科学运算Pandas模块

一、Series数列

Series
Series是一种类似与一维数组的对象,由下面两个部分组成:
values:一组数据(ndarray类型)
index:相关的数据索引标签

Series的创建
第一种:由列表或numpy数组创建
列表创建:
Series([1,2,3,4,5],index=['a','b','c','d','e'],name='Hello')
ndarray创建
a1 = np.array([1,2,3,4,5])
Series(a1,index=["a","b","c","d","e"],name='hello')
第二种:由字典创建:不能在使用index.但是依然存在默认索引
注意:数据源必须为一维数据
dict = {'hello':12,'hey':30}
Series(data=dict)

Series的索引
可以使用中括号取单个索引(此时返回的是指定索引的元素),或者中括号里一个列表取多个索引(此时返回的是一个Series类型)。
s1 = Series(data=[1,2,3],index=['a','b','c'])
----> s1[1] 返回的是指定索引的元素
----> s1[[0,1]] 返回的是一个Series类型
显式索引:
使用index中的元素作为索引值,
使用s.loc[](推荐):注意,loc中括号中放置的一定是显示索引
----> s1.b
----> s1.loc["b"]
隐式索引
使用.iloc[](推荐):iloc中的中括号中必须放置隐式索引
----> s1.iloc[1]

Series切片:隐式索引切片和显示索引切片
显示索引切片:index和loc
s1["a":"c"]根据index切
s1.loc["a":"c"]根据loc切
隐示索引切片:整数索引值和iloc
s1[0:2]根据整数索引值切
s1.iloc[0:2]根据iloc切

Series的基本概念
可以把Series看成一个定长的有序字典
向Series增加一行:相当于给字典增加一组键值对

可以通过shapesizeindex,values等得到series的属性

可以使用s.head(n),tail(n)分别查看前n个和后n个值

当索引没有对应的值时,可能出现缺失数据显示NaN(not a number)的情况

可以使用pd.isnull()pd.notnull(),或s.isnull(),notnull()函数检测缺失数据

 
屏幕快照 2018-11-05 下午8.44.28.png

Series的运算
+ - * /
add()/sub()/mul()/div()
s1.div(s2,fill_value=9)
在运算中自动对齐不同索引的数据,如果索引不对应,则补NaN

二、DataFarme(数据帧)

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

DataFrame(数据帧)的创建
最常用的方法是传递一个字典来创建。DataFrame以字典的键作为每一【列】的名称,以字典的值(一个数组)作为每一列。
此外,DataFrame会自动加上每一行的索引。
使用字典创建的DataFrame后,则columns参数将不可被使用。
同Series一样,若传入的列与字典的键不匹配,则相应的值为NaN。
使用字典创建DataFarme
dict = {"java":[90,22,66],'python':[12,33,66]}
DataFrame(data=dict,index=['章伞','里斯','魍伍'])
使用ndarray创建DataFrame
DataFrame(data=np.random.randint(0,100,size=(3,6)),index=["one","two","three"],columns=["呵","哈","嘿","嘻","嗨","呜"])

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

DataFrame的索引

对列进行索引
-- 通过类似字典的方式 df['q']
-- 通过属性的方式 df.q
可以将DataFrame的列获取为一个Series。返回的Series拥有原DataFrame相同的索引,且name属性也已经设置好了,就是相应的列名。
--- df["呵"]
--- df.呵
--- df[["呵","哈","嘿"]]
修改列索引
df.columns = ['1','2','3',"4","5","6"]

对行进行索引
使用.loc[]加index来进行行索引
使用.iloc[]加整数来进行行索引
同样返回一个Series,index为原来的columns。
--- df.loc["one"]
--- df.loc[["one","two"]]
--- df.loc["one":"three"]
--- df["one":"three"]
--- df["one":"three"]["嘿"]
修改行索引
--- df.index = [1,2,3]

对元素索引的方法
行索引在前,列索引在后
--- df.loc["one"]["哈"]
--- df.iloc[0]["哈"]

DataFrame的列删除
df.drop("列名",axio=1,inplace=True)

DataFarme的切片
--- df.loc["one":"three","呵":"嘿"]
--- df.loc["one":"two"][["呵","呜"]]
--- df.loc["one":"two",["呵","呜","哈"]]
--- df.loc[["one"],["呵","呜","哈"]]

DataFrame的运算
同Series一样:
在运算中自动对齐不同索引的数据
如果索引不对应,则补NaN

处理丢失数据
有两种丢失数据:None、np.nan(NaN)
None是Python自带的,其类型为python object。因此,None不能参与到任何计算中。
np.nan是浮点类型,能参与到计算中。但计算的结果总是NaN。

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

pandas处理空值操作
isnull(). 判断函数
notnull() 判断函数
dropna(): 过滤丢失数据
df.dropna() 可以选择过滤的是行还是列(默认为行):axis中0表示行,1表示的列
fillna(): 填充丢失数据
很多时候将空值全都dropna()掉是不现实的,所以需要用fillna()填充空值。
df.fillna(value=100) 或者 df.fillna(method="ffill",axis=0)
method 控制填充的方式,可以选择前向填充还是后向填充

DataFrame的数据过滤
df.query(expr, inplace=False, **kwargs),可以指定一个字符串形式的筛选条件 逻辑与& 或 | ==

df.shift() 该函数主要的功能就是使数据框中数据整体移动
df.shift(1)

三、创建多层列索引

隐式构造
最常见的方法是给DataFrame构造函数的index或者columns参数传递两个或更多的数组
df = DataFrame(data=np.random.randint(80,100,size=(2,4)),index=['tom','jay'],columns=[['qz','qz','qm','qm'],['chinese','math','chinese','math']])

显示构造pd.MultiIndex.from_
使用数组方式
创建了一个索引对象,该索引对象为二层索引
indexObj = pd.MultiIndex.from_arrays([['qz','qz','qm','qm'],['chinese','math','chinese','math']])
创建DF对象
DataFrame(data=np.random.randint(80,100,size=(2,4)),index=['tom','jar'],columns=indexObj)

 
屏幕快照 2018-11-05 下午10.00.20.png

使用product方式

最简单,推荐使用
col=pd.MultiIndex.from_product([['qizhong','qimo'], ['chinese','math']])
创建DF对象
df = DataFrame(data=np.random.randint(10,100,size=(2,4)),index=['tom','jay'], columns=col)

 
屏幕快照 2018-11-05 下午10.05.06.png

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

多层索引对象的索引与切片操作
注意在对行索引的时候,若一级行索引还有多个,对二级行索引会遇到问题!也就是说,无法直接对二级索引进行索引,必须让二级索引变成一级索引后才能对其进行索引!

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

聚合操作
所谓的聚合操作:平均数,方差,最大值,最小值……
使用value_counts()函数,统计列中各个元素出现次数
使用unique()函数查看一列中有哪些元素

四、pandas的拼接操作(类似数据库的联表)

pandas的拼接分为两种:
级联:pd.concat, pd.append
合并:pd.merge, pd.join

----级联

pandas使用pd.concat级联函数,与np.concatenate函数类似,只是多了一些参数:
objs 级联的对象
axis=0 轴向
keys:列表,列表元素表示的是进行级联的df的一个名称
join='outer' / 'inner':表示的是级联的方式,outer会将所有的项进行级联(忽略匹配和不匹配),而inner只会将匹配的项级联到一起,不匹配的不级联
ignore_index=False

匹配级联
df1 = DataFrame(data=np.random.randint(0,100,size=(3,3)),index=['a','b','c'],columns=['A','B','C'])
pd.concat([df1,df1],axis=0)
不匹配级联
不匹配指的是级联的维度的索引不一致。例如纵向级联时列索引不一致,横向级联时行索引不一致
不匹配级联有2种连接方式:
外连接:补NaN(默认模式)
内连接:只连接匹配的项
df1 = DataFrame(data=np.random.randint(0,100,size=(3,3)),index=['a','b','c'],columns=['A','B','C'])
df2 = DataFrame(data=np.random.randint(0,100,size=(3,3)),index=['a','c','d'],columns=['A','C','D'])
外链接pd.concat([df1,df2],axis=1,join="outer")
内链接pd.concat([df1,df2],axis=0,join="inner")
内链接指定keyspd.concat([df1,df2],axis=1,join="inner",keys=['AAA','BBB'])

df.append()函数级联
由于在后面级联的使用非常普遍,因此有一个函数append专门用于在后面添加
df1.append(df2)

----合并

使用pd.merge()合并
merge与concat的区别在于,merge需要依据某一共同的列来进行合并
使用pd.merge()合并时,会自动根据两者相同column名称的那一列,作为key来进行合并。
注意每一列元素的顺序不要求一致

参数
how:out取并集 inner取交集
on:当有多列相同的时候,可以使用on来指定使用那一列进行合并,on的值为一个列表
一对一合并
df1 = DataFrame({'employee':['Bob','Jake','Lisa'],'group':['Accounting','Engineering','Engineering'],})
df2 = DataFrame({'employee':['Lisa','Bob','Jake'],'hire_date':[2004,2008,2012],})
merge合并:pd.merge(df1,df2)
多对一合并
df3 = DataFrame({'employee':['Lisa','Jake'],'group':['Accounting','Engineering'],'hire_date':[2004,2016]})
df4 = DataFrame({'group':['Accounting','Engineering','Engineering'],'supervisor':['Carly','Guido','Steve']})
pd.merge(df3,df4)
多对多合并

key的规范化使用
当列冲突时,即有多个列名称相同时,需要使用on=来指定哪一个列作为key,配合suffixes指定冲突列名。
pd.merge(df1,df2,on="group",suffixes=('_甲','乙'),how="outer")

注意:当两张表没有可进行连接的列时,可使用left_on和right_on手动指定merge中左右两边的哪一列列作为连接的列

内合并与外合并:
外合并outer:取并集,补NaN
内合并inner:取交集,保留两者都有的key

五、pandas数据处理

1、检测重复行 duplicated()
  使用duplicated()函数检测重复的行,返回元素为布尔类型的Series对象,每个元素对应一行,如果该行不是第一次出现,则元素为True
keep参数:指定保留哪一重复的行数据
True 重复的行

2.删除重复行 drop_duplicates()
  使用drop_duplicates()函数删除重复的行
  drop_duplicates(keep='first/last'/False)

2. 映射:指定替换
  replace()函数:替换元素
  使用replace()函数,对values进行映射操作

Series替换操作replace()
单值替换
  普通替换
  s.replace(to_replace=2,value='two',inplace=True)
  字典替换(推荐)
  s.replace(to_replace={2:'two'},inplace=True)
多值替换
  列表替换
  s.replace(to_replace=[1,5],value=['one','five'])
  字典替换(推荐)
  s.replace(to_replace={3:'three',4:'four'},inplace=True)
参数
  to_replace:被替换的元素
  method:对指定的值使用相邻的值填充替换
  limit:设定填充次数

DataFrame替换操作
单值替换
  普通替换: 替换所有符合要求的元素,没有要替换的值也不会报错:
  df.replace(to_replace=64,value='aaa')
  按列指定单值替换: to_replace={列标签:替换值} ,value='value'
  df.replace(to_replace={2:85},value='eight')
多值替换
  列表替换: to_replace=[] value=[]
  df.replace(to_replace=[9,0],value=['a','b'])
  字典替换(推荐) to_replace={to_replace:value,to_replace:value}
  df.replace(to_replace={1:"one",30:"thirty"})
注意:DataFrame中,无法使用method和limit参数

3. map()函数:新建一列
  map是Series的一个函数
  map()可以映射新一列数据
  map()中可以使用lambd表达式
  map()中可以使用方法,可以是自定义的方法
注意 map()中不能使用sum之类的函数,for循环
df = DataFrame(data=[['zhangsan',1000,'sale'],['lisi',2000,'dev'],['wangwu',3333,'dev']],columns=['name','salary','dep'])
增加名为e_name列:
df['e_name'] = df['name'].map({'lisi':'Tony','zhangsan':'Tom','wangwu':'Jerry'})

map当做一种运算工具,至于执行何种运算,是由map函数的参数决定的
(参数:lambda,函数)

-- 使用自定义函数
  def func():
    ...
    return xxx
  df['salary'].map(func)
-- 使用lambda表达式
  df['salary'].map(lamada x:x..)

注意:并不是任何形式的函数都可以作为map的参数。只有当一个函数具有一个参数且有返回值,那么该函数才可以作为map的参数。

4. 使用聚合操作对数据异常值检测和过滤
使用df.std()函数可以求得DataFrame对象每一列的标准差
此处不再做详细解读

5. 排序
--使用sort_value()排序
d f.sort_values(by="列名",axis=0,ascending=False)
-- 使用.take()函数排序
take()函数接受一个索引列表,用数字表示,使得df根据列表中索引的顺序进行排序
df.take([1,2,0],axis=0)

 
屏幕快照 2018-11-06 下午8.14.29.png

-- 可以借助np.random.permutation()函数随机排序
np.random.permutation(x)可以生成x个从0-(x-1)的随机数列
arr = np.random.permutation(4)
df.take(arr,axis=1)
随机抽样:当DataFrame规模足够大时,直接使用np.random.permutation(x)函数,就配合take()函数实现随机抽样

6.数据分类处理【重点】
数据聚合是数据处理的最后一步,通常是要使每一个数组生成一个单一的数值。

数据分类处理:
  分组:先把数据分为几组
  用函数处理:为不同组的数据应用不同的函数以转换数据
  合并:把不同组得到的结果合并起来
数据分类处理的核心:
  groupby()函数
  groups属性查看分组情况
分组后的聚合操作:分组后的成员中可以被进行运算的值会进行运算,不能被运算的值不进行运算

unstack()与reset_index()对比:
针对多列分组情况,使用unstack(level=1)将上面所得分组数据指定的索引变成列索引。

 
屏幕快照 2018-11-07 下午4.05.50.png

把索引变成列,Series.reset_index()
 
屏幕快照 2018-11-07 下午4.16.23.png

pandas数据读取和写入:

1.pandas提供了一些用于将表格型数据读取为DataFrame对象的函数,期中read_csv和read_table这两个使用最多。
2.使用read_csv读取url获取网络上的数据
3.通过to_excel(path)、to_sql("sql语句",conn)等方式将数据写入对应的文件或数据库

原文地址:https://www.cnblogs.com/john-xiong/p/11854721.html