pandas处理丢失数据 None与np.nan
有两种丢失数据:
-
None
-
np.nan(NaN)
import numpy as np
import pandas as pd
from pandas import Series,DataFrame
df = pd.read_excel(‘students.xlsx’)
df
------------------------------
name age python java c
0 lucy 19.0 90 90.0 90
1 mery NaN 98 89.0 100
2 tom 19.0 89 NaN 95
3 jack 20.0 100 98.0 100
df.dtypes
------------------------------
name object
age float64
python int64
java float64
c int64
dtype: object
type(df.loc[1,"age"])
-----------------------
numpy.float64
# 1. pandas业务表处理的,需要进行运算 np.nan
# 2. object运算效率远低于float类型
- None
None是Python自带的,其类型为python object。因此,None不能参与到任何计算中。
object类型的运算要比int类型的运算慢得多
计算不同数据类型求和时间
%timeit np.arange(1e5,dtype=xxx).sum()
df = DataFrame(data=np.random.randint(0,10,size=(3,3)))
df
--------------------------
0 1 2
0 8 7 9
1 1 3 6
2 4 0 1
# pandas会对None类型做优化,优化成np.nan
df.loc[1,2] = None
df.loc[1,2]
--------------------------
nan
# numpy中,没有对None优化
np.array([1,2,3,np.nan])
--------------------
array([ 1., 2., 3., nan])
- np.nan(NaN)
np.nan是浮点类型,能参与到计算中。但计算的结果总是NaN。
但可以使用np.nan*()函数来计算nan,此时视nan为0。
- pandas中的None与np.nan
- pandas中None与np.nan都视作np.nan
创建DataFrame
使用DataFrame行索引与列索引修改DataFrame数据
- pandas中None与np.nan的操作
- isnull()
- notnull()
- dropna(): 过滤丢失数据
- fillna(): 填充丢失数据
(1)判断函数
- isnull()
- notnull()
df.columns = [“A”,“B”,“C”]
df
-----------------------
A B C
0 8 5 1.0
1 7 3 NaN
2 7 2 8.0
# 得到一个与执行方法对象形状相同的bool类型的新对象
df.isnull()
--------------------
A B C
0 False False False
1 False False True
2 False False False
# 判断一个集合中是否有至少一个True
# 默认判断的是列
df.any()
----------------------------
A True
B True
C True
dtype: bool
# 数据又两种值
# 数值 5 5
# 逻辑值 5 True
(2) 过滤函数
- dropna()
表示过滤空值
axis=0 表示行方向的过滤 axis=1 表示列方向的过滤
# how=“any” 有一个空值就过滤 how=“all” 全部是空值才过滤
df.dropna(axis=1)
-----------------------
A B
0 8 5
1 7 3
2 7 2
df.dropna(how="all")
---------------------------
A B C
0 8 5 1.0
1 7 3 NaN
2 7 2 8.0
df.loc[1] = [np.nan, np.nan, np.nan]
df
-----------------------
A B C
0 8.0 5.0 1.0
1 NaN NaN NaN
2 7.0 2.0 8.0
df.dropna(how="all")
----------------------
A B C
0 8.0 7.0 9.0
2 4.0 0.0 1.0
# 使用drop函数来过滤
# 过滤掉所有行
# labels 行索引或者列索引 以列表的方式传入
df.drop(df.index, axis=0)
--------------------
A B C
df
# 过滤掉一行
df.drop(labels=[0], axis=0)
------------------------
A B C
1 NaN NaN NaN
2 7.0 2.0 8.0
# 过滤掉一列
df.drop(labels=["A"], axis=1)
-------------------------
B C
0 5.0 1.0
1 NaN NaN
2 2.0 8.0
过滤掉包含空值的行或列,需要先找到包含空值的行或列的标签
# 1. 过滤掉包含空值的行,所以先找包含空值的行标签
drop_labels = df.loc[df.isnull().any(axis=1)].index
# 2. 使用包含空值的标签进行过滤
df.drop(drop_labels)
-------------------------------------
A B C
0 8.0 5.0 1.0
2 7.0 2.0 8.0
# 过滤掉包含空值的列
df.loc[1,"B"] = 100
df
------------------------------------
A B C
0 8.0 7.0 9.0
1 NaN 100.0 NaN
2 4.0 0.0 1.0
drop_labels = df.loc[:,df.isnull().any()].columns
df.drop(labels=drop_labels, axis=1)
-----------------------------------------
0
1
2
df.drop(df[(df > 9).any(axis=1)].index)
-------------------------------------
A B C
0 8.0 7.0 9.0
2 4.0 0.0 1.0
可以选择过滤的是行还是列(默认为行)
也可以选择过滤的方式 how = ‘all’
(3) 填充函数 Series/DataFrame
- fillna()
s1 = Series(data=[1,np.nan,3,4,np.nan,5,6])
s1
-------------------------------
0 1.0
1 NaN
2 3.0
3 4.0
4 NaN
5 5.0
6 6.0
dtype: float64
# 以fill_value填充所有空值
s1.fillna(value=100)
------------------------------------
0 1.0
1 100.0
2 3.0
3 4.0
4 100.0
5 5.0
6 6.0
dtype: float64
# 使用method参数,设置相邻数据的填充
# bfill 向后填充 向下填充
# ffill 向前填充 向上填充
s1.fillna(method="ffill", limit=1)
-------------------------------------
0 1.0
1 1.0
2 3.0
3 4.0
4 4.0
5 5.0
6 6.0
dtype: float64
# 可以使用limit参数来修饰填充次数
s1.fillna(value=99, limit=1)
-----------------------------
0 1.0
1 99.0
2 3.0
3 4.0
4 NaN
5 5.0
6 6.0
dtype: float64
s1.loc[5] = np.nan
s1
--------------------
0 1.0
1 NaN
2 3.0
3 4.0
4 NaN
5 NaN
6 6.0
dtype: float64
s1.fillna(method="ffill", limit=1)
------------------------------
0 1.0
1 1.0
2 3.0
3 4.0
4 4.0
5 NaN
6 6.0
dtype: float64
可以选择前向填充还是后向填充
对于DataFrame来说,还要选择填充的轴axis。记住,对于DataFrame来说:
- axis=0:index/行
- axis=1:columns/列