前面知道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。
聚合操作:
所谓的聚合操作:平均数,标准方差,最大值,最小值……
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
行重新设定:
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
设置缺失值:
df1.loc['Tom','英语'] = np.NaN
df1.loc['Jack','数学'] = np.NaN
pandas 中对于空/缺失值的操作:
空值:在pandas中的空值是 ' ';缺失值:在dataframe中为nan或者naT(缺失时间),在series中为none或者nan即可。
1). DataFrame.isna() / DataFrame.isnull:判断是不是缺失值,True表示是,False表示不是。
2). DataFrame.notnull(): 判断是不是缺失值,True表示不是,False表示是。
1 # 构造一个dataframe 2 df = pd.DataFrame([[np.nan, 2, np.nan, 0], 3 [3, 4, "", 1], 4 [np.nan, np.nan, np.nan, 5], 5 [np.nan, 3, "", 4]], 6 columns=list('ABCD')) 7 8 # A B C D 9 # 0 NaN 2.0 NaN 0 10 # 1 3.0 4.0 1 11 # 2 NaN NaN NaN 5 12 # 3 NaN 3.0 4 13 14 # 检测缺失值(针对所有数据) 15 df.isnull() 16 df.isna() 17 df.notnull() 18 19 # 检查哪些列有缺失值,含有NaN的列显示True 20 df.isnull().any() 21 # A True 22 # B True 23 # C True 24 # D False 25 # dtype: bool 26 27 # 统计每列有缺失值的个数 28 df.isnull().sum() 29 # A 3 30 # B 1 31 # C 2 32 # D 0 33 # dtype: int64 34 35 # 查看某列缺失值情况 36 df['A'].isnull()
3). DataFrame.dropna(axis=0, how='any', thresh=None, subset=None, inplace=False):过滤丢失数据,删除含有缺失值的行或列。
axis:维度,axis=0表示index行,axis=1表示columns列,默认为0;
how:"all"表示这一行或列中的元素全部缺失(为nan)才删除这一行或列,"any"表示这一行或列中只要有元素缺失,就删除这一行或列;
thresh:一行或一列中至少出现了thresh个才删除;
subset:在某些列的子集中选择出现了缺失值的列删除,不在子集中的含有缺失值得列或行不会删除(有axis决定是行还是列);
inplace:对原数据有影响,默认False。
1 # 默认参数:删除行,只要有空值就会删除,不替换 2 df.dropna() 3 df.dropna(axis=0, how='any', inplace=False) 4 df.dropna(axis="index", how='any', inplace=False) 5 6 # 删除掉全是空值的行,不替换 7 df.dropna(how='all') 8 df.dropna(axis=0, how='all', inplace=False) 9 df.dropna(axis="index", how='all', inplace=False) 10 11 # 删除掉全是空值的列,替换 12 df.dropna(axis=1, how='all', inplace=True) 13 df.dropna(axis="columns", how='all', inplace=True) 14 15 # 删除掉至少出现过两个缺失值的行 16 df.dropna(thresh=2) 17 18 # 删除这个subset中的含有缺失值的行 19 print df.dropna(subset=['name', 'born'])
4). DataFrame.fillna(value=None, method=None, axis=None, inplace=False, limit=None, downcast=None, **kwargs):填充缺失值。
value:用于缺失值位置填充的值,可以是单个值,或者字典(key是列名,value是值);
axis:填充维度,从行开始或是从列开始;
method:{'backfill', 'bfill', 'pad', 'ffill', None}, default None。定义了填充空值的方法, pad / ffill表示用前面行/列的值,填充当前行/列的空值,如果axis =1,那么就是横向的前面的值替换后面的缺失值,如果axis=0,那么则是上面的值替换下面的缺失值。backfill / bfill表示用后面行/列的值,填充当前行/列的空值,缺失值后面的一个值代替前面的缺失值。注意method这个参数不能与value同时出现;
limit:确定填充的个数,如果limit=2,则只填充两个缺失值。如果method被指定,对于连续的空值,这段连续区域,最多填充前 limit 个空值(如果存在多段连续区域,每段最多填充前 limit 个空值)。如果method未被指定, 在该axis下,最多填充前 limit 个空值(不论空值连续区间是否间断);
downcast:dict, default is None,字典中的项为,为类型向下转换规则。或者为字符串“infer”,此时会在合适的等价类型之间进行向下转换,比如float64 to int64 if possible。
1 # 横向用缺失值前面的值替换缺失值 2 df.fillna(axis=1,method='ffill') 3 4 # 纵向用缺失值上面的值替换缺失值 5 df.fillna(axis=0,method='ffill') 6 7 # 所有缺失值填充为10 8 df.fillna(10) 9 10 # 不同的列用不同的值填充 11 values = {'A':0,'B':1,'C':2,'D':3} 12 df.fillna(value=values) 13 14 # 只将'D'列的缺失值填充为0 15 df.fillna({"D":0})
空值替换:缺失值是NAN,空值是没有显示,即' '。替换空值,需要把含有空值的那一列提出来单独处理,然后在放进去就好。
1 # 1.C列有空值,先把C列的缺失值填充为0 2 df_= df['C'].fillna(0) 3 4 # 2.将C列的空值,即 ' ' 替换成1 5 df_[df_==' '] = 1 6 7 # 3.把填充完成的C列重新放到df中 8 df['C'] = df_
9 # 或者一步到位,将C列的空值,即 ' ' 替换成1
10 df.loc[df['C']=='','C'] = 1
数据分析:删除行比较合适,行代表的是一条数据,列会影响到所有的数据。机器学习:如果是行当中的空值比较多那就删行,列中空值比较多就删列。
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行
pandas去重操作
:
drop_duplicate()方法是对DataFrame格式的数据,去除特定列下面的重复行,返回DataFrame格式的数据。
data.drop_duplicates(subset=['A','B'],keep='first',inplace=True):
subset : 用来指定特定的列;上面格式中subset对应的值是列名,表示只考虑 'A','B' 两列,将这两列对应值相同的行进行去重。默认值为subset=None表示考虑所有列。
keep : {‘first’, ‘last’, False}, default ‘first’,删除重复项并保留第一次出现的项
inplace : boolean, default False,是直接在原来数据上修改还是保留一个副本
1 data.duplicated() # 判断是否是重复的项 2 data.duplicated().sum() # 统计记录重复数 3 data.drop_duplicates() # 移除重复的项
统计DataFrame中每一列的唯一值,并输出唯一值的数量
1 df['column'].unique() # 列出该列的唯一值 2 3 df['column'].value_counts() # 统计每个唯一值出现了多少次
pandas数据排序:
1). df.sort_values():既可以根据列数据,也可根据行数据排序。注意必须指定by参数,即必须指定哪几行或哪几列;无法根据index名和columns名排序(由.sort_index()执行)
格式:DataFrame.sort_values(by, axis=0, ascending=True, inplace=False, kind='quicksort', na_position='last')
axis:{0 or ‘index’, 1 or ‘columns’}, default 0,默认按照列排序,即纵向排序;如果为1,则是横向排序。
by:str or list of str;如果axis=0,那么by="列名";如果axis=1,那么by="行名"。
ascending:布尔型,True则升序,如果by=['列名1','列名2'],则该参数可以是[True, False],即第一字段升序,第二个降序。
inplace:布尔型,是否用排序后的数据框替换现有的数据框。
kind:排序方法,{‘quicksort’, ‘mergesort’, ‘heapsort’}, default ‘quicksort’。似乎不用太关心。
na_position:{‘first’, ‘last’}, default ‘last’,默认缺失值排在最后面。
1 # 构造dataframe数据 2 df = pd.DataFrame({'b':[1,2,3,2],'a':[4,3,2,1],'c':[1,3,8,2]},index=[2,0,1,3]) 3 # b a c 4 # 2 1 4 1 5 # 0 2 3 3 6 # 1 3 2 8 7 # 3 2 1 2 8 9 # 按b列升序排序 10 df.sort_values(by='b') #等同于df.sort_values(by='b',axis=0) 11 # b a c 12 # 2 1 4 1 13 # 0 2 3 3 14 # 3 2 1 2 15 # 1 3 2 8 16 17 # 按行3升序排列 18 df.sort_values(by=3,axis=1) #必须指定axis=1 19 # a b c 20 # 2 4 1 1 21 # 0 3 2 3 22 # 1 2 3 8 23 # 3 1 2 2 24 25 # 先按b列降序,再按a列升序排序 26 df.sort_values(by=['b','a'],axis=0,ascending=[False,True]) 27 # b a c 28 # 1 3 2 8 29 # 3 2 1 2 30 # 0 2 3 3 31 # 2 1 4 1
【注意】指定多列(多行)排序时,先按排在前面的列(行)排序,如果内部有相同数据,再对相同数据内部用下一个列(行)排序,以此类推。如何内部无重复数据,则后续排列不执行。即首先满足排在前面的参数的排序,再排后面参数。
2). df. sort_index():默认根据行标签对所有行排序,或根据列标签对所有列排序,或根据指定某列或某几列对行排序。注意:df. sort_index()可以完成和df. sort_values()完全相同的功能,但python更推荐用只用df. sort_index()对“根据行标签”和“根据列标签”排序,其他排序方式用df.sort_values()。
格式:sort_index(axis=0, level=None, ascending=True, inplace=False, kind='quicksort', na_position='last', sort_remaining=True, by=None)
axis:0按照行名排序;1按照列名排序
level:默认None
ascending:默认True升序排列;False降序排列
inplace:默认False,否则排序之后的数据直接替换原来的数据框
kind:排序方法,{‘quicksort’, ‘mergesort’, ‘heapsort’}, default ‘quicksort’
na_position:缺失值默认排在最后{"first","last"}
by:按照某一列或几列数据进行排序
1 # 构造dataframe数据 2 df = pd.DataFrame({'b':[1,2,2,3],'a':[4,3,2,1],'c':[1,3,8,2]},index=[2,0,1,3]) 3 # b a c 4 # 2 1 4 1 5 # 0 2 3 3 6 # 1 3 2 8 7 # 3 2 1 2 8 9 # 1.默认按“行标签”升序排列(推荐) 10 df.sort_index() # 默认按“行标签”升序排序,或df.sort_index(axis=0, ascending=True) 11 b a c 12 0 2 3 3 13 1 3 2 8 14 2 1 4 1 15 3 2 1 2 16 17 # 2.按“列标签”升序排列(推荐) 18 df.sort_index(axis=1) # 按“列标签”升序排序 19 # a b c 20 # 2 4 1 1 21 # 0 3 2 3 22 # 1 2 3 8 23 # 3 1 2 2
数据的简单保存与读取:
1 pd.read_csv('test.csv') # 读取csv文件 2 3 data.to_csv('test.csv') # 保存csv文件
补充:基本的统计数据。data. describe() ;data.info()。
pandas‘高级函数’:映射
map:映射 replace:替换值 rename:替换行索引 apply:相同的事情重复做。
代码演示理解:
1 ''' 2 fillna()填充NaN,只有是nan值的时候 fillna才可以,其他的不行,fillna()只认识nan。下面的 ?? , " "可以用replace:替换值,需要过滤的字符当作key,需要替换成什么写成val 3 ''' 4 # (1).replace:替换值 5 df = DataFrame({'汽车品牌':['宝马','奔驰','奥迪','雷车','??'],'游戏机':['小霸王','psp','gameboy','Switch','']}) 6 7 rep = {'??':np.NaN,'':np.NaN} 8 9 df.replace(to_replace=rep).fillna(0) # 替换成0 10 df.replace(to_replace=rep).fillna('国产') # 替换成‘国产’ 11 12 # (2).rename:替换行索引 13 df1 = DataFrame(np.random.randint(0,100,(5,5)),ind1ex=list('东南西北中'),columns=list('金木水火土')) 14 15 rep1 = {'东':'东邪','西':'西毒','南':'南帝','北':'北丐','中':'中神通','东南':'孔雀','西北':'阿宝','西南':'孟获','东北':'李晶'} 16 17 df1.rename(rep1) # 直接替换(映射) 18 19 df1.T.rename(rep1) # 列能不能替换,可以转置之后再映射 20 21 # (3).map(function) 逐列进行修改的,所以调用的时候都是Series.map() df1['土'].map() Series配合df使用的 22 df1['风'] = df1['土'].map(lambda x : x * 2 -10) # 映射关系:土 × 2 -10 ----> 风 23 24 # 映射关系:风 ----> 山 25 def convert(item): 26 if item <=100: 27 return '垃圾' 28 else: 29 return '大神' 30 df1['山'] = df1['风'].map(convert) 31 32 # (4).transform,和map()比较相似 33 df1['林'] = df1['风'].transform(convert)