第6章 缺失数据
在接下来的两章中,会接触到数据预处理中比较麻烦的类型,即缺失数据和文本数据(尤其是混杂型文本)
Pandas在步入1.0后,对数据类型也做出了新的尝试,尤其是Nullable类型和String类型,了解这些可能在未来成为主流的新特性是必要的
import pandas as pd
import numpy as np
df = pd. read_csv( 'data/table_missing.csv' )
df. head( )
School
Class
ID
Gender
Address
Height
Weight
Math
Physics
0
S_1
C_1
NaN
M
street_1
173
NaN
34.0
A+
1
S_1
C_1
NaN
F
street_2
192
NaN
32.5
B+
2
S_1
C_1
1103.0
M
street_2
186
NaN
87.2
B+
3
S_1
NaN
NaN
F
street_2
167
81.0
80.4
NaN
4
S_1
C_1
1105.0
NaN
street_4
159
64.0
84.8
A-
一、缺失观测及其类型
1. 了解缺失信息
(a)isna和notna方法
对Series使用会返回布尔列表
df[ 'Physics' ] . isna( ) . head( )
0 False
1 False
2 False
3 True
4 False
Name: Physics, dtype: bool
df[ 'Physics' ] . notna( ) . head( )
0 True
1 True
2 True
3 False
4 True
Name: Physics, dtype: bool
对DataFrame使用会返回布尔表
df. isna( ) . head( )
School
Class
ID
Gender
Address
Height
Weight
Math
Physics
0
False
False
True
False
False
False
True
False
False
1
False
False
True
False
False
False
True
False
False
2
False
False
False
False
False
False
True
False
False
3
False
True
True
False
False
False
False
False
True
4
False
False
False
True
False
False
False
False
False
但对于DataFrame我们更关心到底每列有多少缺失值
df. isna( ) . sum ( )
School 0
Class 4
ID 6
Gender 7
Address 0
Height 0
Weight 13
Math 5
Physics 4
dtype: int64
此外,可以通过第1章中介绍的info函数查看缺失信息
df. info( )
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 35 entries, 0 to 34
Data columns (total 9 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 School 35 non-null object
1 Class 31 non-null object
2 ID 29 non-null float64
3 Gender 28 non-null object
4 Address 35 non-null object
5 Height 35 non-null int64
6 Weight 22 non-null float64
7 Math 30 non-null float64
8 Physics 31 non-null object
dtypes: float64(3), int64(1), object(5)
memory usage: 2.6+ KB
(b)查看缺失值的所以在行
以最后一列为例,挑出该列缺失值的行
df[ df[ 'Physics' ] . isna( ) ]
School
Class
ID
Gender
Address
Height
Weight
Math
Physics
3
S_1
NaN
NaN
F
street_2
167
81.0
80.4
NaN
8
S_1
C_2
1204.0
F
street_5
162
63.0
33.8
NaN
13
S_1
C_3
1304.0
NaN
street_2
195
70.0
85.2
NaN
22
S_2
C_2
2203.0
M
street_4
155
91.0
73.8
NaN
(c)挑选出所有非缺失值列
使用all就是全部非缺失值,如果是any就是至少有一个不是缺失值
df[ df. notna( ) . all ( 1 ) ]
School
Class
ID
Gender
Address
Height
Weight
Math
Physics
5
S_1
C_2
1201.0
M
street_5
159
68.0
97.0
A-
6
S_1
C_2
1202.0
F
street_4
176
94.0
63.5
B-
12
S_1
C_3
1303.0
M
street_7
188
82.0
49.7
B
17
S_2
C_1
2103.0
M
street_4
157
61.0
52.5
B-
21
S_2
C_2
2202.0
F
street_7
194
77.0
68.5
B+
25
S_2
C_3
2301.0
F
street_4
157
78.0
72.3
B+
27
S_2
C_3
2303.0
F
street_7
190
99.0
65.9
C
28
S_2
C_3
2304.0
F
street_6
164
81.0
95.5
A-
29
S_2
C_3
2305.0
M
street_4
187
73.0
48.9
B
2. 三种缺失符号
(a)np.nan
np.nan是一个麻烦的东西,首先它不等与任何东西,甚至不等于自己
np. nan == np. nan
False
np. nan == 0
False
np. nan == None
False
在用equals函数比较时,自动略过两侧全是np.nan的单元格,因此结果不会影响
df. equals( df)
True
其次,它在numpy中的类型为浮点,由此导致数据集读入时,即使原来是整数的列,只要有缺失值就会变为浮点型
type ( np. nan)
float
pd. Series( [ 1 , 2 , 3 ] ) . dtype
dtype('int64')
pd. Series( [ 1 , np. nan, 3 ] ) . dtype
dtype('float64')
此外,对于布尔类型的列表,如果是np.nan填充,那么它的值会自动变为True而不是False
pd. Series( [ 1 , np. nan, 3 ] , dtype= 'bool' )
0 True
1 True
2 True
dtype: bool
但当修改一个布尔列表时,会改变列表类型,而不是赋值为True
s = pd. Series( [ True , False ] , dtype= 'bool' )
s[ 1 ] = np. nan
s
0 1.0
1 NaN
dtype: float64
在所有的表格读取后,无论列是存放什么类型的数据,默认的缺失值全为np.nan类型
因此整型列转为浮点;而字符由于无法转化为浮点,因此只能归并为object类型(‘O’),原来是浮点型的则类型不变
df[ 'ID' ] . dtype
dtype('float64')
df[ 'Math' ] . dtype
dtype('float64')
df[ 'Class' ] . dtype
dtype('O')
(b)None
None比前者稍微好些,至少它会等于自身
None ==