2.pandas入门介绍,
2.pandas入门介绍,
前面知道NumPy是 Python 语言的一个扩展程序库,支持大量的维度数组与矩阵运算,也针对数组运算提供大量的数学函数库。numpy是基于c语言开发,所以这使得numpy的运行速度很快,高效率运行就是numpy的一大优势。但numpy的特长并不是在于数据处理,而是在于能非常方便地实现科学计算,所以对数据进行处理时用的numpy情况并不是很多,因为需要处理的数据一般都是带有列标签和index索引的,而numpy并不支持这些,这时就需要pandas了,Pandas的主要工作就是做数据分析,pandas继承了numpy 我们要使用的是pandas而不是numpy。Pandas是基于Numpy构建的库,在数据处理方面可以把它理解为numpy加强版 。
数据分析中:样本是(行) 特征是(列)。
pandas的优缺点。优点:pandas相比于Excel,matlab,tableau等更加的灵活,处理大数据的问题上更加有优势,读取excel文件的时候,pandas更加快,处理速度快。缺点:操控方面相对比较僵硬,pandas当中的函数要清晰使用,statsmodels统计库(bug百出,官网提供的文档大部分不友好),scipy高数(stats,使用方法太繁琐)。
pandas的处理速度。为什么不用mysql? 慢:文件操作慢;pandas:快在于将数据加载到内存了。
数据分析使用的库:numpy作为依赖库;pandas数据分析库;matplotlib直观的数据可视化库;seaborn辅助库(库中含有调色板),图形更加丰富;pyecharts:简易的数据可视化库,电商中比较常用;,,,。
pandas中有两大数据类型。Series 级数(索引是有序的,一维的);DataFrame 结构化数据(二维的表)。
1. Series级数
Series是一种类似一维数组的数据结构,由一组数据和与之相关的index组成,即由values:一组数据(ndarray类型) 和 key:相关的数据索引标签两个部分组成。这个结构一看似乎与dict字典差不多,我们知道字典是一种无序的数据结构,而pandas中的Series的数据结构不一样,它相当于定长有序的字典,并且它的index和value之间是独立的,两者的索引还是有区别的,Series的index是可变的,而dict字典的key值是不可变的。Series是将 序列 和 hash 融合在一起了。序列:索引有序,索引是枚举类型;hash:键是无序的,键是关联类型的。pandas中的两大数据类型都可以使用对象和属性的方式来获取值和赋值,在pandas中,string也是object。
Series的创建 :
可由列表或numpy数组创建:默认索引为0到N-1的整数型索引。(list,tuple,dict,ndarry)强制转换为Series类型 。
1 # 由列表创建,默认索引为0到4的整数型索引 2 s0 = Series([1,2,3,4,5]) 3 s0[1] # 2
4 # 由numpy数组创建 5 s1 = Series(np.array(list('ABCD'))) 6 7 # 由字典(hash)创建,字典的key会被Series当作是index 8 s2 = Series({'A':1,"B":2,"C":3}) 9 10 # 通过设置index参数指定索引 --> {a:甲,b:乙,c:} 11 s3 = Series(data=list('甲乙丙丁'),index=list('abcd'))
Series的索引和切片:
1). 常规索引:可以使用中括号取单个索引(此时返回的是元素类型),或者中括号里一个列表取多个索引(此时返回的仍然是一个Series类型)。
2). 显式索引:
- 使用index中的关联类型作为索引值;- 使用.loc[](推荐)。可以理解为pandas是ndarray的升级版,但是Series也是dict的升级版
3). 隐式索引:
- 使用整数作为索引值;- 使用.iloc[](推荐)
1 # 常规索引 2 s3[0] # ‘甲’ 3 s3['a'] # ‘甲’ 4 5 # 显式索引 6 s3.loc['a'] # ‘甲’ 7 8 # 隐式索引 9 s3.iloc[0] # ‘甲’
4). 切片:
1 # 常规切片,左闭右开 2 s3[0:-1] 3 # a 甲 4 # b 乙 5 # c 丙 6 # Name: username, dtype: object 7 8 # 显式切片,全闭区间 9 s3.loc['a':'d'] 10 # a 甲 11 # b 乙 12 # c 丙 13 # d 丁 14 # Name: username, dtype: object 15 16 # 隐式切片,左闭右开 17 s3.iloc[0:-1] 18 # a 甲 19 # b 乙 20 # c 丙 21 # Name: username, dtype: object
Series的属性:
可以把Series看成一个定长的有序字典。
1 ''' 2 ndim:维度 3 shape:形状 4 size:获取元素的长度 5 dtype:数据类型 6 index:获取所有的索引 7 values:获取所有的值 8 name:获取名称 9 head():快速查看Series对象的样式,获取前5条数据 10 tail():快速查看Series对象的样式,获取最后5条数据 11 '''
代码演示示例:
1 s3.shape # (4,) 2 s3.size # 4 3 s3.ndim # 1 4 s3.name # 'username' 5 s3.dtype # dtype('O') 表示字符串类型 6 s3.index # Index(['a', 'b', 'c', 'd'], dtype='object') 7 s3.keys() # Index(['a', 'b', 'c', 'd'], dtype='object') 8 s3.valuse # array(['甲', '乙', '丙', '丁'], dtype=object) 9 s3.head(n=5) 10 s3.tail(n=5)
检测缺失数据:
当索引没有对应的值时,可能出现缺失数据显示NaN(not a number)的情况。注意:np.NaN !== np.NaN;可以使用pd.isnull(),pd.notnull(),或自带isnull(),notnull()函数检测缺失数据。
1 # 造一含有NaN值的Series数据 2 s5 = Series(data=range(4),index=list('abcd')) # NaN是float 3 s5['c'] = np.nan # 将索引c 的值变为nan 4 s5 5 # a 0.0 6 # b 1.0 7 # c NaN 8 # d 3.0 9 # dtype: float64 10 11 # 检测缺失数据 12 cond = pd.isnull(s5) # 相当于s5.isnull() 13 cond 14 # a False 15 # b False 16 # c True 17 # d False 18 # dtype: bool 19 # 检查到NaN值之后,将nan值的数据变成 0 20 s5[cond]= 0 21 # a 0.0 22 # b 1.0 23 # c 0.0 24 # d 3.0 25 # dtype: float64 26 27 s5['c'] = np.nan # 将索引c 的值变为nan 28 29 # 检测缺失数据 30 cond_fa = s5.notnull() # 相当于pd.notnull(s5) 31 cond_fa 32 # a True 33 # b True 34 # c False 35 # d True 36 # dtype: bool 37 # 检查到NaN值之后,将nan值筛选掉 38 s5[cond_fa] 39 # a 0.0 40 # b 1.0 41 # d 3.0 42 # dtype: float64
Series之间的运算:
NaN+任何值都是NaN。在运算中自动对齐不同索引的数据,如果索引不对应,则补NaN。
1 s5 * 3 2 # a 0.0 3 # b 3.0 4 # c 0.0 5 # d 9.0 6 # dtype: float64 7 8 s6 = Series(range(5),list('bcdef')) 9 10 s5.add(s6) # 相当于 s5+s6 11 # a NaN 12 # b 1.0 13 # c 1.0 14 # d 5.0 15 # e NaN 16 # f NaN 17 # dtype: float64
2. DataFrame
DataFrame是一个【表格型】的数据结构,可以看做是【由Series组成的字典】(共用同一个索引)。DataFrame由按一定顺序排列的多列数据组成。设计初衷是将Series的使用场景从一维拓展到多维。DataFrame既有行索引,也有列索引。行索引:index;列索引:columns;值:values(numpy的二维数组)。我们的 训练集(一些二维的数据)都是二维的,那么Series满足不了这个条件,xy轴,轴上的一点(0,0)。DataFrame每一列可以是不同类型的值集合,所以DataFrame你也可以把它视为不同数据类型同一index的Series集合。
DataFrame的创建:
最常用的方法是传递一个字典来创建。DataFrame以字典的键作为每一【列】的名称,以字典的值(一个数组)作为每一列的值。此外,DataFrame会自动加上每一行的索引(和Series一样)。同Series一样,若传入的列与字典的键不匹配,则相应的值为NaN。
1 df1 = DataFrame(data={'数学':[10,20,30,40,50], 2 '语文':[1,2,3,4,5], 3 '英语':[10,11,12,13,14]}, 4 index=['Tom','Jhon','Jack','Marry','Jurray'], 5 columns=['英语','数学','语文']) 6
# 英语 数学 语文 7 # Tom 10 10 1 8 # Jhon 11 20 2 9 # Jack 12 30 3 10 # Marry 13 40 4 11 # Jurray 14 50 5
DataFrame属性:
values、columns、index、shape、ndim、dtypes。
1 # 行索引 2 df1.index # Index(['雷军', '不知妻美', '不知爹富', '马云', '罗太军'], dtype='object') 3 4 # 列索引 5 df1.columns # Index(['英语', '数学', '语文'], dtype='object') 6 7 df1.dtypes 8 # 英语 int64 9 # 数学 int64 10 # 语文 int64 11 # dtype: object 12 13 df1.size # 15
14 df1.ndim # 2
DataFrame的索引:
1). 对列进行索引(获取某一列): [ ] 默认只能取列索引。- 通过类似字典的方式;- 通过属性的方式。可以将DataFrame的列获取为一个Series。返回的Series拥有原DataFrame相同的索引,且name属性也已经设置好了,就是相应的列名。
df1['语文'] ---> 获取‘语文’列
2). 对行进行索引(获取某一行):- 使用.loc[]加index来进行行索引;- 使用.iloc[]加整数来进行行索引。同样返回一个Series,index为原来的columns。
df1.loc['Tom'] ---> 获取‘Tom’行
df1.iloc[0] ---> 获取第0行,等于‘Tom’行
3). 对元素进行索引(获取某一个元数/值):- 使用列索引;- 使用行索引(iloc[3,1]相当于两个参数;iloc[[3,3]] 里面的[3,3]看做一个参数);- 使用values属性(二维numpy数组)
df1.loc['Tom','英语'] ---> 获取‘Tom’行,‘英语’列的这个元素的值
df1.iloc[0,0] ---> 获取第0行,第0列的这个元素的值,和df1.loc['Tom','英语']结果一样
1 # 对列进行索引, [ ] 默认只能取列索引 2 df1['语文'] # 获取为一个Series ,相当于【 df1.语文 】 3 # Tom 1 4 # Jhon 2 5 # Jack 3 6 # Marry 4 7 # Jurray 5 8 # Name: 语文, dtype: int64 9 10 df1.语文 # 不建议这样获取列 11 df1['Tom'] # 会报错 12 13 14 # 对行进行索引 15 df1.loc['Tom'] # 显式loc 16 # 英语 10 17 # 数学 10 18 # 语文 1 19 # Name: Tom, dtype: int64 20 21 df1.iloc[0] # 隐式iloc 22 # 英语 10 23 # 数学 10 24 # 语文 1 25 # Name: Tom, dtype: int64 26 27 # 对元素进行索引 28 df1.loc['Tom','英语'] # 10 29 30 df1.iloc[0,0] # 10
4). 切片操作:
获取某些行和某些列的值,可以是多个值
1 # 使用行索引显式loc切片,全闭区间 2 df1.loc['Tom':'Jack'] # 获取Tom到Jack行的数据,针对行 3 # 英语 数学 语文 4 # Tom 10 10 1 5 # Jhon 11 20 2 6 # Jack 12 30 3 7 8 df1.loc['Tom':'Jack','英语':'数学'] # 获取Tom到Jack行,英语到数学列的数据 9 # 英语 数学 10 # Tom 10 10 11 # Jhon 11 20 12 # Jack 12 30 13 14 15 # 使用行索引隐式iloc切片,左开右闭 16 df1.iloc[1:2] # 获取第1行到第2行的数据(不包含第2行),针对行 17 # 英语 数学 语文 18 # Jhon 11 20 2 19 20 df1.iloc[0:2 , 0:2] # 获取第0行到第2行,第0列到第2列的数据(不包含第2行和第2列) 21 # 英语 数学 22 # Tom 10 10 23 # Jhon 11 20
DataFrame的运算:
Dataframe的运算同Series一样。
下图是Python 操作符与pandas操作函数的对应表:
Series与DataFrame之间的运算:
使用pandas操作函数:axis=0:以列为单位操作(参数必须是列),对所有列都有效;axis=1:以行为单位操作(参数必须是行),对所有行都有效。
列方向:df1.add(s) #默认列相加;行方向: (df1.T + s).T。
处理丢失的数据:
df1.loc['Tom','英语'] = np.NaN
df1.loc['Jack','数学'] = np.NaN
pandas 中对于空的操作:
isnull():是空值,notnull():不是空值,dropna() :过滤空值,fillna() :填充空值。
数据分析:删除行比较合适,行代表的是一条数据,列会影响到所有的数据。机器学习:如果是行当中的空值比较多那就删行,列中空值比较多就删列。
1 # 判断是否为空值 2 df1.loc[:,'英语'].isnull() 3 # Tom True 4 # Jhon True 5 # Jack True 6 # Marry True 7 # Jurray True 8 # Name: 英语, dtype: bool 9 10 # 当该行中所有的元素都为空则删除 11 df1.dropna(how='all') 12 13 # 当该行中所有的元素都为空则删除 14 df1.dropna(how='any',axis=1,inplace=True) 15 16 # 填充空值 17 df1.fillna(value=None, method=None, axis=None, inplace=False, limit=None, #downcast=None, **kwargs)
聚合操作:
所谓的聚合操作:平均数,标准方差,最大值,最小值……
1 df1.sum() # 默认是对列进行操作 2 df1.mean() # 默认是对列进行操作 3 df1.max() # 求列的最大值 4 df1.var() # 样本方差,表示的数据的波动性 5 df1.std() # 样本标准差
pandas的拼接操作:
pandas的拼接分为两种:级联:pd.concat, pd.append;合并:pd.merge, pd.join。
回顾numpy的级联:
1 np.concatenate([np.random.randint(0,100,(5,4)),np.random.rand(5,4),np.random.randn(5,4)],axis=1)
1). 简单级联:
行合并:pd.concat([df1,df2],axis=0)。和np.concatenate一样,优先增加行数(默认axis=0)。注意index在级联时可以重复。
列合并:pd.concat([df1,df2],axis=1)。不建议用,concat它不是联表查询,只擅长当union(垂直的 axis=0),水平合并一定不要用。
1 # 垂直的内连接,join='inner' ,会删除含有NaN的行或列 2 pd.concat([df1,df2],axis=0,join='inner') # index在级联时可以重复 3 4 # 水平内连接 5 pd.concat([df1,df2],axis=1,join='inner') 6 7 # 外连接,不匹配的项补NaN 8 pd.concat([df1,df2],axis=0,join='outer') 9 10 # ignore_index=True忽略重复索引 11 pd.concat([df1,df2],axis=0,join='outer',ignore_index=True) 12 13 # 使用多层索引 keys ,解决重复问题 14 pd.concat([df1,df2],axis=0,join='outer',keys=['df1','df2']) 15 # a b c 16 # df1 0 a0 b0 c0 17 # 1 a1 b1 c1 18 # 2 a2 b2 c2 19 # df2 2 a2 b2 c2 20 # 3 a3 b3 c3 21 # 4 a4 b4 c4
2). 不匹配级联:
不匹配指的是级联的维度的索引不一致。例如纵向级联时列索引不一致,横向级联时行索引不一致;有3种连接方式:
- 外连接:补NaN(默认模式)
- 内连接:只连接匹配的项
-连接指定轴 join_axes 显示某一格dataframe 中的列
3).使用append()函数添加:
由于在后面级联的使用非常普遍,因此有一个函数append专门用于在后面添加,append 和 concat 相似,只能直接做垂直:df1.append(df2)
4). 使用pd.merge()合并:
merge与concat的区别在于,merge需要依据某一共同的行或列来进行合并,使用pd.merge()合并时,会自动根据两者相同column名称的那一列,作为key来进行合并。注意每一列元素的顺序不要求一致
pd.merge(DataFrame1,DataFrame2, how=‘inner’, on=None, left_on=None, right_on=None, left_index=False, right_index=False, sort=True, suffixes=(’_x’, ‘_y’))
pd.merge(DataFrame1,DataFrame2) == DataFrame1.merge(DataFrame2)
参数:
how:默认为inner,可设为inner/outer/left/right
on:根据某个字段进行连接,必须存在于两个DateFrame中(若未同时存在,则需要分别使用left_on和right_on来设置)
left_on:左连接,以DataFrame1中用作连接键的列
right_on:右连接,以DataFrame2中用作连接键的列
left_index:将DataFrame1行索引用作连接键
right_index:将DataFrame2行索引用作连接键
sort:根据连接键对合并后的数据进行排列,默认为True
suffixes:对两个数据集中出现的重复列,新数据集中加上后缀_x,_y进行区别
代码演示区别:
1 pd.DataFrame({'lkey':['foo','bar','baz','foo'], 'value':[1,2,3,4]}) 2 # lkey value 3 # 0 foo 1 4 # 1 bar 2 5 # 2 baz 3 6 # 3 foo 4 7 8 pd.DataFrame({'rkey':['foo','bar','qux','bar'], 'value':[5,6,7,8]}) 9 # rkey value 10 # 0 foo 5 11 # 1 bar 6 12 # 2 qux 7 13 # 3 bar 8 14 15 # inner链接 16 dataDf1.merge(dataDf2, left_on='lkey',right_on='rkey') 17 # lkey value_x rkey value_y 18 # 0 foo 1 foo 5 19 # 1 foo 4 foo 5 20 # 2 bar 2 bar 6 21 # 3 bar 2 bar 8 22 23 # Outer链接 24 dataDf1.merge(dataDf2, left_on='lkey', right_on='rkey', how='outer') 25 # lkey value_x rkey value_y 26 # 0 foo 1.0 foo 5.0 27 # 1 foo 4.0 foo 5.0 28 # 2 bar 2.0 bar 6.0 29 # 3 bar 2.0 bar 8.0 30 # 4 baz 3.0 NaN NaN 31 # 5 NaN NaN qux 7.0 32 33 # left链接 34 dataDf1.merge(dataDf2, left_on='lkey', right_on='rkey',how='left') 35 # lkey value_x rkey value_y 36 # 0 foo 1 foo 5.0 37 # 1 bar 2 bar 6.0 38 # 2 bar 2 bar 8.0 39 # 3 baz 3 NaN NaN 40 # 4 foo 4 foo 5.0 41
41 # right链接 42 dataDf1.merge(dataDf2, left_on='lkey', right_on='rkey',how='right') 43 # lkey value_x rkey value_y 44 # 0 foo 1.0 foo 5 45 # 1 foo 4.0 foo 5 46 # 2 bar 2.0 bar 6 47 # 3 bar 2.0 bar 8 48 # 4 NaN NaN qux 7
【注意】1).当有多个key相同时使用,使用on=显式指定哪一列为key;当左右两边的key都不相等时,使用left_on和right_on指定左右两边的列作为key。
2).内合并:只保留两者都有的key(默认模式);外合并 how='outer':补NaN;左合并、右合并:how='left',how='right'。
列冲突的解决:
当列冲突时,即有多个列名称相同时,需要使用on=来指定哪一个列作为key,配合suffixes指定冲突列名,可以使用suffixes=自己指定后缀。
1 dataDf1.merge(dataDf2, left_on='lkey', right_on='rkey', how='right', suffixes=('_df1', '_df2')) 2 # lkey value_df1 rkey value_df2 3 # 0 foo 1.0 foo 5 4 # 1 foo 4.0 foo 5 5 # 2 bar 2.0 bar 6 6 # 3 bar 2.0 bar 8 7 # 4 NaN NaN qux 7
pandas删除操作:
Dataframe.drop(labels=0,axis=0,inplace=True):labels=0表示 第0行 ,inplace=True表示对原数据 产生影响。
1 df1.drop(labels=0,axis=0,inplace=True) # 删除第0行 2 df1.drop(0) # 删除第0行 3 df1.drop([0,1]) # 删除第0,1行
行重新设定:
Dataframe.set_index('id',inplace=True)
1 dataDf1 2 # lkey value 3 # 0 foo 1 4 # 1 bar 2 5 # 2 baz 3 6 # 3 foo 4 7 8 dataDf1.set_index(['value'],inplace=True) # 将'value'设置为index 9 dataDf1 10 # lkey 11 # value 12 # 1 foo 13 # 2 bar 14 # 3 baz 15 # 4 foo 16 17 dataDf1.reset_index(inplace=True) # 将index返回回dataframe中 18 dataDf1 19 # value lkey 20 # 0 1 foo 21 # 1 2 bar 22 # 2 3 baz 23 # 3 4 foo
统计出现的次数:
1 data[ column_1 ].value_counts()
数据的简单保存与读取:
1 pd.read_csv('test.csv') # 读取csv文件 2 3 data.to_csv('test.csv') # 保存csv文件
补充:基本的统计数据。data. describe() ;data.info()。
相关内容
- 暂无相关文章
评论关闭