pandas基础--缺失数据处理

pandas含有是数据分析工作变得更快更简单的高级数据结构和操作工具,是基于numpy构建的。

本章节的代码引入pandas约定为:import pandas as pd,另外import numpy as np也会用到。

官方介绍:pandas - Python Data Analysis Library (pydata.org)

7 缺失数据处理

缺失数据是数据分析中的常见现象。pandas使用浮点值NaN(Not a Number)表示浮点和非浮点数组中的缺失数据。它只是一个便于被检测出来的标记而已。python内置的None值也会被当作NA处理。

 1 >>> string_data = pd.Series(['aardvark', 'artichoke', np.nan, 'avocado'])
 2 >>> string_data
 3 0     aardvark
 4 1    artichoke
 5 2          NaN
 6 3      avocado
 7 dtype: object
 8 >>> string_data.isnull()
 9 0    False
10 1    False
11 2     True
12 3    False
13 dtype: bool
14 >>> string_data[0] = None
15 >>> string_data.isnull()  
16 0     True
17 1    False
18 2     True
19 3    False
20 dtype: bool
21 >>>

NA处理方法。

方式 说明
dropna 根据各标签的值中是否存在缺失数据对轴标签进行过滤,可通过阈值调节对缺失值的容忍度,也就是thresh参数,如设置为2,则至少行(列)有两个非NaN值才保留。
fillna 用指定值或插值方法(如ffill或bfill)填充缺失数据
isnull 返回一个含有布尔值的对象,这些布尔值表示哪些值是缺失值NA,该对象的类型和源类型一样
notnull isnull的否定式

部分官方说明:

pandas.DataFrame.dropna — pandas 1.3.4 documentation (pydata.org)

pandas.DataFrame.fillna — pandas 1.3.4 documentation (pydata.org)

>>> string_data = pd.Series(['aardvark', 'artichoke', np.nan, 'avocado'])
>>> string_data
0     aardvark
1    artichoke
2          NaN
3      avocado
dtype: object
    
>>> string_data.dropna()
0     aardvark
1    artichoke
3      avocado
dtype: object
    
>>> string_data.fillna(value='haha')
0     aardvark
1    artichoke
2         haha
3      avocado
dtype: object

7.1 滤除缺失数据

过滤掉缺失数据的方法有多种,可通过dropna实现。

 1 >>> from numpy import nan as NA
 2 >>> data = pd.Series([1, NA, 3.5, NA, 7]) 
 3 >>> data.dropna()
 4 0    1.0
 5 2    3.5
 6 4    7.0
 7 dtype: float64
 8 >>> data[data.isnull()] 
 9 1   NaN
10 3   NaN
11 dtype: float64
12 >>> data[data.notnull()] 
13 0    1.0
14 2    3.5
15 4    7.0
16 dtype: float64

对于DataFrame,可能希望丢弃全NA或含有NA的行或列。

 1 >>> data = pd.DataFrame([[1, 1.6, 3], [1, NA, NA], [NA, NA, NA], [NA, 6.5, 3]]) 
 2 >>> data
 3      0    1    2
 4 0  1.0  1.6  3.0
 5 1  1.0  NaN  NaN
 6 2  NaN  NaN  NaN
 7 3  NaN  6.5  3.0
 8 >>>
 9 >>> cleaned = data.dropna()  #默认丢弃任何含有缺失值的行
10 >>> cleaned
11      0    1    2
12 0  1.0  1.6  3.0
13 >>> data.dropna(how='all')  #只丢弃全为NA的行
14      0    1    2
15 0  1.0  1.6  3.0
16 1  1.0  NaN  NaN
17 3  NaN  6.5  3.0
18 >>> data[4] = NA
19 >>> data
20      0    1    2   4
21 0  1.0  1.6  3.0 NaN
22 1  1.0  NaN  NaN NaN
23 2  NaN  NaN  NaN NaN
24 3  NaN  6.5  3.0 NaN
25 >>> data.dropna(axis=1, how='all')  #丢弃列,且列的所有值为NaN才丢弃
26      0    1    2
27 0  1.0  1.6  3.0
28 1  1.0  NaN  NaN
29 2  NaN  NaN  NaN
30 3  NaN  6.5  3.0
31 >>>

另一个滤除DataFrame行的问题涉及到时间序列数据。如果只想留下一部分观测数据,可以用thresh参数实现。

 1 >>> df = pd.DataFrame(np.random.randn(7, 3)) 
 2 >>> df 
 3           0         1         2
 4 0  0.752301  1.360969 -0.474561
 5 1  0.466749  0.563536  1.978575
 6 2  0.223606  0.414722  0.094315
 7 3 -1.687511 -0.116227  0.442363
 8 4  0.705580 -0.131169 -0.868425
 9 5 -0.158964 -0.164512 -0.937150
10 6 -0.281537 -1.579942 -0.562886
11 >>> df.loc[:4, 1] = NA
12 >>> df.loc[:2, 2] = NA 
13 >>> df
14           0         1         2
15 0  0.752301       NaN       NaN
16 1  0.466749       NaN       NaN
17 2  0.223606       NaN       NaN
18 3 -1.687511       NaN  0.442363
19 4  0.705580       NaN -0.868425
20 5 -0.158964 -0.164512 -0.937150
21 6 -0.281537 -1.579942 -0.562886
>>> df.dropna(thresh=2)  #行至少有两个非NaN值才保留
          0         1         2
3 -0.845402       NaN -0.037411
4 -0.563560       NaN -0.992985
5  0.227253 -1.649384 -0.754437
6  1.090384  0.980745  0.661543

7.2 填充缺失数据

fillna方法可实现将缺失值替换为一个常数值。

官方文档:pandas.DataFrame.fillna — pandas 1.3.4 documentation (pydata.org)

 1 >>> df 
 2           0         1         2
 3 0  0.752301       NaN       NaN
 4 1  0.466749       NaN       NaN
 5 2  0.223606       NaN       NaN
 6 3 -1.687511       NaN  0.442363
 7 4  0.705580       NaN -0.868425
 8 5 -0.158964 -0.164512 -0.937150
 9 6 -0.281537 -1.579942 -0.562886
10 >>> df.fillna(0) 
11           0         1         2
12 0  0.752301  0.000000  0.000000
13 1  0.466749  0.000000  0.000000
14 2  0.223606  0.000000  0.000000
15 3 -1.687511  0.000000  0.442363
16 4  0.705580  0.000000 -0.868425
17 5 -0.158964 -0.164512 -0.937150
18 6 -0.281537 -1.579942 -0.562886
19 >>> df.fillna({1:0.5, 3:-1})  #第1列的NA替换为0.5,第3列的NA替换为-1
20           0         1         2
21 0  0.752301  0.500000       NaN
22 1  0.466749  0.500000       NaN
23 2  0.223606  0.500000       NaN
24 3 -1.687511  0.500000  0.442363
25 4  0.705580  0.500000 -0.868425
26 5 -0.158964 -0.164512 -0.937150
27 6 -0.281537 -1.579942 -0.562886
28 >>>

fillna默认会返回新对象。但也可以对现有对象进行就地修改。

 1 >>> _ = df.fillna(0, inplace=True) 
 2 >>> df
 3           0         1         2
 4 0  0.752301  0.000000  0.000000
 5 1  0.466749  0.000000  0.000000
 6 2  0.223606  0.000000  0.000000
 7 3 -1.687511  0.000000  0.442363
 8 4  0.705580  0.000000 -0.868425
 9 5 -0.158964 -0.164512 -0.937150
10 6 -0.281537 -1.579942 -0.562886
11 >>>

对reindex有效的插值方法也可以用于fillna。

 1 >>> df = pd.DataFrame(np.random.randn(6, 3))
 2 >>> df.loc[2:, 1] = NA
 3 >>> df.loc[4:, 2] = NA 
 4 >>> df
 5           0         1         2
 6 0 -1.433489  0.162951 -0.664600
 7 1  0.033722 -0.478252  0.480072
 8 2 -0.000977       NaN -1.555649
 9 3 -0.947501       NaN  0.089918
10 4  1.360481       NaN       NaN
11 5 -0.966030       NaN       NaN
12 >>> df.fillna(method='ffill')
13           0         1         2
14 0 -1.433489  0.162951 -0.664600
15 1  0.033722 -0.478252  0.480072
16 2 -0.000977 -0.478252 -1.555649
17 3 -0.947501 -0.478252  0.089918
18 4  1.360481 -0.478252  0.089918
19 5 -0.966030 -0.478252  0.089918
20 >>> df.fillna(method='ffill', limit=2) 
21           0         1         2
22 0 -1.433489  0.162951 -0.664600
23 1  0.033722 -0.478252  0.480072
24 2 -0.000977 -0.478252 -1.555649
25 3 -0.947501 -0.478252  0.089918
26 4  1.360481       NaN  0.089918
27 5 -0.966030       NaN  0.089918

下表是fillna的参数参考。

参数 说明
value 用于填充缺失值的标量值或字典对象
method 插值方式,如果函数调用时未指定其他参数的话,默认为“ffill”
axis 带填充的轴,默认为axis=0
limit (对于向前或先后填充)可以连续填充的最大数量
posted @ 2020-02-03 17:26  zhengcixi  阅读(560)  评论(0编辑  收藏  举报
回到顶部