数据清洗-缺失值的处理

前言

在数据分析时,经常会遇到数据缺失的情况。而Pandas这个Python数据分析库提供了多种方法来处理缺失值。

缺失值是什么?

pandas中的缺失值

  • NaN(NotaNumber)是缺失值的标志
  • 方法:isna(),notna()

pandas使用浮点值NaN(NotaNumber)表示缺失数据,使用NA(NotAvailable)

表示缺失值。可以通过isnull()、isna()或notnull()、notna()方法判断某个值是否为缺失

值。

Nan通常表示一个无效的或未定义的数字值,是浮点数的一种特殊取值,用于表示那

些不能表示为正常数字的情况,如0/0、∞-∞等数学运算的结果。nan与任何值(包括

它自身)进行比较的结果都为False。例如在Python中,nan==nan返回False。

NA一般用于表示数据不可用或缺失的情况,它的含义更侧重于数据在某种上下文中是

缺失或不存在的,不一定特指数字类型的缺失。

na和nan都用于表示缺失值,但nan更强调是数值计算中的特殊值,而na更强调数

据的可用性或存在性。

python 复制代码
import pandas as pd
import numpy as np
s=pd.Series([np.nan,pd.NA,None])
print(s)
s.isna()

0     NaN
1    <NA>
2    None
dtype: object
0    True
1    True
2    True
dtype: bool

准备数据

python 复制代码
import numpy as np
import pandas as pd
df = pd.DataFrame({
    "name":["bob","jack","talk","tell","see","sala"],
    "age":[10,15,36,np.nan,40,np.nan],
    "height":[1.65,1.70,np.nan,1.7,1.85,1.80]
})
print(df)

   name   age  height
0   bob  10.0    1.65
1  jack  15.0    1.70
2  talk  36.0     NaN
3  tell   NaN    1.70
4   see  40.0    1.85
5  sala   NaN    1.80

查看缺失值

方法:isna()或者isnull()

python 复制代码
print(df.isna())
print(df.isna().sum())
    name    age  height
0  False  False   False
1  False  False   False
2  False  False    True
3  False   True   False
4  False  False   False
5  False   True   False
name      0
age       2
height    1
dtype: int64

删除缺失值

常用方法

python 复制代码
df.dropna() #删除含有缺失值的行,默认情况删除行,df.dropna(axis=1) axis=1删除含有缺失值的列

	name	age	height
0	bob	    10.0	1.65
1	jack	15.0	1.70
4	see	    40.0	1.85
python 复制代码
df.dropna(subset=["age"]) #如果某列有缺失值,则删除这一行

	name	age	height
0	bob	    10.0	1.65
1	jack	15.0	1.70
2	talk	36.0	NaN
4	see	    40.0	1.85
python 复制代码
df.dropna(axis=0, how="all") #how="all",所有值都是缺失值才会删除 默认any


    name	age	    height
0	bob	    10.0	1.65
1	jack	15.0	1.70
2	talk	36.0	NaN
3	tell	NaN	    1.70
4	see	    40.0	1.85
5	sala	NaN	    1.80
python 复制代码
df.dropna(thresh=2)# 如果至少由n个不是缺失值,就保留

	name	age	height
0	bob	    10.0	1.65
1	jack	15.0	1.70
2	talk	36.0	NaN
3	tell	NaN	    1.70
4	see	    40.0	1.85
5	sala	NaN	    1.80

填充缺失值

python 复制代码
df.fillna(10) #所有的缺失值,都填充10

name	    age	    height
0	bob	    10.0	1.65
1	jack	15.0	1.70
2	talk	36.0	10.00
3	tell	10.0	1.70
4	see	    40.0	1.85
5	sala	10.0	1.80
python 复制代码
df.fillna({"age":10,"height":2.26}) #使用字典填充 age 缺失值填充10 height填充 2.26

	name	age	height
0	bob	    10.0	1.65
1	jack	15.0	1.7
2	talk	36.0	2.26
3	tell	10.0	1.7
4	see    	40.0	1.85
5	sala	10.0	1.8
python 复制代码
df.fillna({"age":df["age"].mean(),"height":df["height"].mean()}) #使用字典填充 按照平均值填充

	name	age	height
0	bob	    10.00	1.65
1	jack	15.00	1.70
2	talk	36.00	1.74
3	tell	25.25	1.70
4	see	    40.00	1.85
5	sala	25.25	1.80
python 复制代码
df.fillna(df[["age","height"]].mean()) #使用平均值填充

	name	age	height
0	bob	    10.00	1.65
1	jack	15.00	1.70
2	talk	36.00	1.74
3	tell	25.25	1.70
4	see	    40.00	1.85
5	sala	25.25	1.80

注意df.fillna(df[["age","height"]].mean()) 为啥两层中括号 [["age","height"]]

pandas中使用两层中括号df[["age"]].mean()的原因

在pandas中,使用 df.fillna(df[["age"]].mean()) 时采用两层中括号是为了保持数据结构的一致性,这涉及到pandas中索引操作的一个重要区别:

核心区别:

  1. 一层中括号 df["age"] 返回的是一个 Series对象
  • 结果是一维数组结构
  • .mean() 会返回一个标量值(单个数字)
  1. 两层中括号 df[["age"]] 返回的是一个 DataFrame对象
  • mean() 会返回一个标量值(单个数字)
  • mean() 会返回一个DataFrame对象,索引为列名,值为均值

实际作用:

使用两层中括号的主要好处是:

  • 保持数据对齐 :当使用 fillna() 时,DataFrame格式的均值会自动根据列名进行对齐,只填充对应列的缺失值。
  • 支持多列操作 :如果需要同时处理多列,可以方便地扩展为 df.fillna(df[["age", "income"]].mean())。
  • 避免广播问题 :使用DataFrame格式可以避免标量值被广播到所有列的风险。

因此,当你只想填充特定列的缺失值而不影响其他列时,使用两层中括号是一个良好的实践,可以确保操作的精确性和可预测性。

python 复制代码
df.ffill() #使用前面的相邻值进行填充

	name	age	    height
0	bob	    10.0	1.65
1	jack	15.0	1.70
2	talk	36.0	1.70
3	tell	36.0	1.70
4	see	    40.0	1.85
5	sala	40.0	1.80
python 复制代码
df.bfill()#使用后面的相临值进行填充

name	age	height
0	bob	    10.0	1.65
1	jack	15.0	1.70
2	talk	36.0	1.70
3	tell	40.0	1.70
4	see	    40.0	1.85
5	sala	NaN	    1.80

案例练习

复制代码
df=pd.read_csv("test.csv",keep_default_na=False) #可以通过keep_default_na参数设置是否将空白值设置为缺失值。
print(df.head(6))


           日期  最高气温  最低气温
0  2025-07-01  33.0  24.6
1  2025-07-02            
2  2025-07-03  33.3  27.7
3  2025-07-04  35.1  27.6
4              31.6  26.4
5  2025-07-06  31.6  22.1

开始

复制代码
df=pd.read_csv("test.csv")  
print(df.head(6))


           日期  最高气温  最低气温
0  2025-07-01  33.0  24.6
1  2025-07-02   NaN   NaN
2  2025-07-03  33.3  27.7
3  2025-07-04  35.1  27.6
4         NaN  31.6  26.4
5  2025-07-06  31.6  22.1
python 复制代码
df=pd.read_csv("test.csv")
df["日期"]=pd.to_datetime(df["日期"])
print(df.head(6))
# df=df.interpolate(method="linear")
df=df.fillna(df[["最高气温","最低气温"]].mean().round(2))
print(df.head(6))


          日期  最高气温  最低气温
0 2025-07-01  33.0  24.6
1 2025-07-02   NaN   NaN
2 2025-07-03  33.3  27.7
3 2025-07-04  35.1  27.6
4 2025-07-04  31.6  26.4
5 2025-07-06  31.6  22.1
          日期   最高气温   最低气温
0 2025-07-01  33.00  24.60
1 2025-07-02  31.83  24.49
2 2025-07-03  33.30  27.70
3 2025-07-04  35.10  27.60
4 2025-07-04  31.60  26.40
5 2025-07-06  31.60  22.10

折线图

python 复制代码
import matplotlib.pyplot as plt
from matplotlib import rcParams
# 设置中文正常显示
rcParams['font.family'] = 'SimHei'
plt.figure(figsize=(12, 6))

# 绘制最高和最低气温曲线
plt.plot(df['日期'], df['最高气温'], 'r', marker='o', label='最高气温')
plt.plot(df['日期'], df['最低气温'], 'b-', marker='o', label='最低气温')

# 填充温差区域
plt.fill_between(df['日期'], df['最低气温'], df['最高气温'], alpha=0.1, color='gray')
# 设置图表属性
plt.title(f'2025年7月份气温变化趋势')
plt.xlabel('日期')
plt.ylabel('气温 (°C)')
plt.grid(True, alpha=0.3)
plt.legend()

# 设置x轴标签旋转角度
plt.xticks(rotation=45)

# 调整布局
plt.tight_layout()

# 显示图表
plt.show()
 
相关推荐
末世灯光3 小时前
时间序列入门第一问:它和普通数据有什么不一样?(附 3 类典型案例)
人工智能·python·机器学习·时序数据
开心-开心急了3 小时前
Flask入门教程——李辉 第一、二章关键知识梳理(更新一次)
后端·python·flask
锦***林3 小时前
用 Python 写一个自动化办公小助手
开发语言·python·自动化
www.023 小时前
微信克隆人,聊天记录训练专属AI(2.WeClone训练模型)
人工智能·python·微信·聊天克隆人·微信克隆人
Gitpchy5 小时前
Day 20 奇异值SVD分解
python·机器学习
MediaTea5 小时前
Python 第三方库:matplotlib(科学绘图与数据可视化)
开发语言·python·信息可视化·matplotlib
草莓熊Lotso5 小时前
C++ 方向 Web 自动化测试入门指南:从概念到 Selenium 实战
前端·c++·python·selenium
gddkxc6 小时前
AI CRM中的数据分析:悟空AI CRM如何帮助企业优化运营
人工智能·信息可视化·数据分析
我是李武涯6 小时前
PyTorch Dataloader工作原理 之 default collate_fn操作
pytorch·python·深度学习