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。

 

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

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)

 

2.pandas入门介绍

全文结束