03 -2 numpy与pandas中isnull()、notnull()、dropna()、fillna()处理丢失数据的理解与实例

本文介绍了如何在numpy和pandas中处理缺失值,包括None和np.nan的区别,以及如何使用isnull、notnull、dropna和fillna进行数据清理。在pandas中,None和np.nan被视为相同并转换为np.nan。文章通过实例展示了如何过滤、填充缺失值,并讨论了不同参数如axis、method和limit的用法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

引入三剑客

import numpy as np
import pandas as pd
from pandas import Series,DataFrame

处理丢失数据

1.有两种丢失数据:

  • None: Python自带的数据类型 不能参与到任何计算中
  • np.nan(NaN): float类型 能参与计算,但结果总是NaN
np.nan + 9            结果为:nan 

2. np.nan(NaN)

数组直接运算会得到nan,但可以使用np.nan*()函数来计算nan,此时视nan为0。

ndarr1 = np.array([1,2,3,np.nan])
ndarr1
np.sum(ndarr1)
结果为:
nan
np.nansum(ndarr1) # nan*()遇到nan会把nan当作0来处理
结果为:
6.0

Series和DataForm可以直接处理nan

s1 = Series([1,2,3,np.nan])
s1.sum() #Series 直接可以处理nan的情况
结果为:6.0
df1 = DataFrame([1,2,3,np.nan])
df1.sum() #DataFrame 直接可以处理nan的情况
结果为:
0    6.0
dtype: float64

3. pandas中的None与NaN

1) pandas中None与np.nan都视作np.nan

用randint创建一个5*5的DataFrame作为例子

Series 和 DataForm 如果遇到None 就会把 None 转换成 numpy.nan

df1 = DataFrame(data=np.random.randint(0,20,size=(5,5)),columns=list("abcde"))
df1
abcde
018184106
1612884
25151822
3218101614
4141321014

使用DataFrame行索引与列索引修改一下DataFrame数据(弄出来一些None和NaN)

df1["b"][1] = None
df1["c"].iloc[2] = None
df1.iloc[2].loc["d"] = np.nan # 自己显式地去设置nan不太好 大家平时不要这么做
df1
abcde
01818.04.0106
16NaN8.084
2515.0NaN22
3218.010.01614
41413.02.01014

2) pandas中None与np.nan的操作

  • isnull()
  • notnull()
  • dropna(): 过滤丢失数据
  • fillna(): 填充丢失数据

(1)判断函数

  • isnull()
  • notnull()
df1.isnull() # 返回一个同样形状的DataFrame 如果是空这个位置就是True 否则就是False
abcde
0FalseFalseFalseFalseFalse
1FalseTrueFalseFalseFalse
2FalseFalseTrueFalseFalse
3FalseFalseFalseFalseFalse
4FalseFalseFalseFalseFalse
df1.notnull() # 不是空值返回True 是空值就是False
abcde
0TrueTrueTrueTrueTrue
1TrueFalseTrueTrueTrue
2TrueTrueFalseTrueTrue
3TrueTrueTrueTrueTrue
4TrueTrueTrueTrueTrue

配合any使用,可以查看每一行是否存在空值 可以控制axis来改变查看方向

df1.isnull().any() # 默认看每一列 只要有True就是True
结果为:
a    False
b     True
c     True
d    False
e    False
dtype: bool

如果想看每一行的中 有没有空值 可以改变axis

df1.isnull().any(axis=0) # axis 默认是 0 是竖直方向
df1.isnull().any(axis=1) # 通过这种方式 可以找到有空值的样本
结果为:
0    False
1     True
2     True
3    False
4    False
dtype: bool

(2) 过滤函数

  • dropna()

可以选择过滤的是行还是列(默认为行)

df1.dropna() # 如果有空值 就把整行都干掉
df1.dropna(axis=0) # 默认是对行进行处理
abcde
01818.04.0106
3218.010.01614
41413.02.01014
# 如果不确定axis到底是横还是竖 可以自己先创建一个假数据 试一试
df1.dropna(axis=1) # 对有空值的列进行处理
ade
018106
1684
2522
321614
4141014

也可以选择过滤的方式 how = ‘all’

df1.dropna(how="any") # 只要有空值 就干掉
abcde
01818.04.0106
3218.010.01614
41413.02.01014
df1.dropna(how="all") # 这一行所有的值都是空值 才干掉
abcde
01818.04.0106
16NaN8.084
2515.0NaN22
3218.010.01614
41413.02.01014
df1.iloc[2] = np.nan
df1
abcde
018.018.04.010.06.0
16.0NaN8.08.04.0
2NaNNaNNaNNaNNaN
32.018.010.016.014.0
414.013.02.010.014.0:
df1.dropna(how="all")
abcde
018.018.04.010.06.0
16.0NaN8.08.04.0
32.018.010.016.014.0
414.013.02.010.014.0

(3) 填充函数 Series/DataFrame

  • fillna()

可以指定value

df1.fillna(value=0) # 遇到空值 可以设置成我们制定的值
abcde
018.018.04.010.06.0
16.00.08.08.04.0
20.00.00.00.00.0
32.018.010.016.014.0
414.013.02.010.014.0
df1.fillna(value=10)
abcde
018.018.04.010.06.0
16.010.08.08.04.0
210.010.010.010.010.0
32.018.010.016.014.0
414.013.02.010.014.0

也可以选择从前面找值来填充还是从后面找值来填充

pad / ffill 从前面找值来填充

backfill/ bfill 从后面找值来填充

df1.fillna(method="ffill")
abcde
018.018.04.010.06.0
16.018.08.08.04.0
26.018.08.08.04.0
32.018.010.016.014.0
414.013.02.010.014.0
df1.fillna(method="bfill")
abcde
018.018.04.010.06.0
16.018.08.08.04.0
22.018.010.016.014.0
32.018.010.016.014.0
414.013.02.010.014.0

虽然填充了值 但并不影响df1原先的值,

abcde
018.018.04.010.06.0
16.0NaN8.08.04.0
2NaNNaNNaNNaNNaN
32.018.010.016.014.0
414.013.02.010.014.0

还可以指定是在寻找值时候的轴线

df1.fillna(method="ffill",axis=0) # axis 默认是0 竖直找  前面已做过
df1.fillna(method="ffill",axis=1) # axis 1 水平找
abcde
018.018.04.010.06.0
16.06.08.08.04.0
2NaNNaNNaNNaNNaN
32.018.010.016.014.0
414.013.02.010.014.0

还可以限定最多往前(往后)填充几个NaN

df1["c"].iloc[1]=np.nan
df1
abcde
018.018.04.010.06.0
16.0NaNNaN8.04.0
2NaNNaNNaNNaNNaN
32.018.010.016.014.0
414.013.02.010.014.0
df1.fillna(method="ffill",limit=2) # 限制往前找几个
abcde
018.018.04.010.06.0
16.018.04.08.04.0
26.018.04.08.04.0
32.018.010.016.014.0
414.013.02.010.014.0

对于DataFrame来说,还要选择填充的轴axis。记住,对于DataFrame来说:

  • axis=0:index/行
  • axis=1:columns/列

使用limit来限定往后找几个

axis 指定是横着找还是竖着找

method 指定找前面还是找后面

注意:value参数是不能跟method参数共用的

df.fillna(method='bfill',axis=1,limit=1)
abcde
018.018.04.010.06.0
16.0NaN8.08.04.0
2NaNNaNNaNNaNNaN
32.018.010.016.014.0
414.013.02.010.014.0

============================================

练习7:

  1. 简述None与NaN的区别
  2. 假设张三李四参加模拟考试,但张三因为突然想明白人生放弃了英语考试,因此记为None,请据此创建一个DataFrame,命名为df3
  3. 老师决定根据用数学的分数填充张三的英语成绩,如何实现? 用李四的英语成绩填充张三的英语成绩?

============================================

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值