3.4 利用Pandas进行数据清洗和数据规整化

本文详细介绍了数据清洗中的缺失数据处理方法,包括数据滤除和填充,并通过实例演示了如何使用dropna()和fillna()函数。此外,讲解了数据合并的不同方式,如行追加和列连接,以及如何利用merge()函数进行数据关联。最后,涉及了数据排序,包括值排序和排名操作,展示了如何根据成绩和年龄对数据进行排序和排名分析。

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

在这里插入图片描述
本文章是3.4、3.5的内容,如果想要源代码和数据可以看以下链接:
https://download.youkuaiyun.com/download/Ahaha_biancheng/83338868

3.4 数据清洗

3.4.1 缺失数据处理

主要有数据滤除和数据填充两类方法

缺失数据被表示为NaN, 赋值时使用np.nan

◆  样本容量大,忽略缺失行

◆  样本容量较小,采用合适的值来填充

例3-9:从studentsInfo.xlsx的Group1表单读取数据,滤除部分缺失数据,填充部分缺失数据。

import pandas as pd
import numpy as np
stu = pd.read_excel('data/studentsInfo.xlsx', index_col=0)
stu
性别年龄身高体重省份成绩月生活费课程兴趣案例教学
序号
1male20.017070.0LiaoNingNaN800.054
2male22.018071.0GuangXi77.01300.034
3maleNaN18062.0FuJian57.01000.024
4male20.017772.0LiaoNing79.0900.044
5male20.0172NaNShanDong91.0NaN55
6male20.017975.0YunNan92.0950.055
7female21.016653.0LiaoNing80.01200.045
8female20.016247.0AnHui78.01000.044
9female20.016247.0AnHui78.01000.044
10male19.016976.0HeiLongJiang88.01100.055

3.4.1.1 数据滤除

dropna()函数删除空值所在行或列,产生新数据对象,不改变原对象

在这里插入图片描述

# 缺省删除包含有缺失值的行(序号1、3、5的行被滤除)
stu.dropna() 
性别年龄身高体重省份成绩月生活费课程兴趣案例教学
序号
2male22.018071.0GuangXi77.01300.034
4male20.017772.0LiaoNing79.0900.044
6male20.017975.0YunNan92.0950.055
7female21.016653.0LiaoNing80.01200.045
8female20.016247.0AnHui78.01000.044
9female20.016247.0AnHui78.01000.044
10male19.016976.0HeiLongJiang88.01100.055
# 保留有效数据个数≥8的行(序号5的行被滤除)
stu.dropna(thresh=8) 
性别年龄身高体重省份成绩月生活费课程兴趣案例教学
序号
1male20.017070.0LiaoNingNaN800.054
2male22.018071.0GuangXi77.01300.034
3maleNaN18062.0FuJian57.01000.024
4male20.017772.0LiaoNing79.0900.044
6male20.017975.0YunNan92.0950.055
7female21.016653.0LiaoNing80.01200.045
8female20.016247.0AnHui78.01000.044
9female20.016247.0AnHui78.01000.044
10male19.016976.0HeiLongJiang88.01100.055
# 未改变原始值
stu
性别年龄身高体重省份成绩月生活费课程兴趣案例教学
序号
1male20.017070.0LiaoNingNaN800.054
2male22.018071.0GuangXi77.01300.034
3maleNaN18062.0FuJian57.01000.024
4male20.017772.0LiaoNing79.0900.044
5male20.0172NaNShanDong91.0NaN55
6male20.017975.0YunNan92.0950.055
7female21.016653.0LiaoNing80.01200.045
8female20.016247.0AnHui78.01000.044
9female20.016247.0AnHui78.01000.044
10male19.016976.0HeiLongJiang88.01100.055

3.4.1.2 数据填充

fillna()函数可以实现NaN数据的批量填充,也可以对指定列进行填充;
填充操作产生新的数据对象,原始数据不会被修改

填充有两种基本思路:

  ◆  用默认值填充
  ◆  用已有数据的均值/中位数来填充

在这里插入图片描述

例3-9“年龄”和“体重”列有缺失数据

◆  同年级学生年龄差距不大,用默认值填充
◆  体重用平均值来填充
# 按列填充,构造{列索引名:值}形式的字典对象作为实参
stu.fillna({'年龄':21, '体重':stu['体重'].mean()})
性别年龄身高体重省份成绩月生活费课程兴趣案例教学
序号
1male20.017070.000000LiaoNingNaN800.054
2male22.018071.000000GuangXi77.01300.034
3male21.018062.000000FuJian57.01000.024
4male20.017772.000000LiaoNing79.0900.044
5male20.017263.666667ShanDong91.0NaN55
6male20.017975.000000YunNan92.0950.055
7female21.016653.000000LiaoNing80.01200.045
8female20.016247.000000AnHui78.01000.044
9female20.016247.000000AnHui78.01000.044
10male19.016976.000000HeiLongJiang88.01100.055
# 用前一行数据替换当前行的空值,第一行没有填充
stu.fillna(method='ffill')
性别年龄身高体重省份成绩月生活费课程兴趣案例教学
序号
1male20.017070.0LiaoNingNaN800.054
2male22.018071.0GuangXi77.01300.034
3male22.018062.0FuJian57.01000.024
4male20.017772.0LiaoNing79.0900.044
5male20.017272.0ShanDong91.0900.055
6male20.017975.0YunNan92.0950.055
7female21.016653.0LiaoNing80.01200.045
8female20.016247.0AnHui78.01000.044
9female20.016247.0AnHui78.01000.044
10male19.016976.0HeiLongJiang88.01100.055
# 对于全是数字的文件,可以设置用标量填充所有的缺失值
stu.fillna(0)
性别年龄身高体重省份成绩月生活费课程兴趣案例教学
序号
1male20.017070.0LiaoNing0.0800.054
2male22.018071.0GuangXi77.01300.034
3male0.018062.0FuJian57.01000.024
4male20.017772.0LiaoNing79.0900.044
5male20.01720.0ShanDong91.00.055
6male20.017975.0YunNan92.0950.055
7female21.016653.0LiaoNing80.01200.045
8female20.016247.0AnHui78.01000.044
9female20.016247.0AnHui78.01000.044
10male19.016976.0HeiLongJiang88.01100.055
# 对于全是数字的文件,可以设置全用平均值填充
stu.fillna(stu.mean())
性别年龄身高体重省份成绩月生活费课程兴趣案例教学
序号
1male20.00000017070.000000LiaoNing80.0800.00000054
2male22.00000018071.000000GuangXi77.01300.00000034
3male20.22222218062.000000FuJian57.01000.00000024
4male20.00000017772.000000LiaoNing79.0900.00000044
5male20.00000017263.666667ShanDong91.01027.77777855
6male20.00000017975.000000YunNan92.0950.00000055
7female21.00000016653.000000LiaoNing80.01200.00000045
8female20.00000016247.000000AnHui78.01000.00000044
9female20.00000016247.000000AnHui78.01000.00000044
10male19.00000016976.000000HeiLongJiang88.01100.00000055
# 用每列的中位数填充
stu.fillna(stu.median())
性别年龄身高体重省份成绩月生活费课程兴趣案例教学
序号
1male20.017070.0LiaoNing79.0800.054
2male22.018071.0GuangXi77.01300.034
3male20.018062.0FuJian57.01000.024
4male20.017772.0LiaoNing79.0900.044
5male20.017270.0ShanDong91.01000.055
6male20.017975.0YunNan92.0950.055
7female21.016653.0LiaoNing80.01200.045
8female20.016247.0AnHui78.01000.044
9female20.016247.0AnHui78.01000.044
10male19.016976.0HeiLongJiang88.01100.055

3.4.2 去除重复数据

例3-10 从文件studentsInfo.xlsx的“Group1”页中读取数据,去除重复数据。

obj.drop_duplicates()

stu = pd.read_excel("data/studentsInfo.xlsx", index_col=0)
stu
性别年龄身高体重省份成绩月生活费课程兴趣案例教学
序号
1male20.017070.0LiaoNingNaN800.054
2male22.018071.0GuangXi77.01300.034
3maleNaN18062.0FuJian57.01000.024
4male20.017772.0LiaoNing79.0900.044
5male20.0172NaNShanDong91.0NaN55
6male20.017975.0YunNan92.0950.055
7female21.016653.0LiaoNing80.01200.045
8female20.016247.0AnHui78.01000.044
9female20.016247.0AnHui78.01000.044
10male19.016976.0HeiLongJiang88.01100.055
# 序号8、9的行重复,序号9的行被滤除
stu.drop_duplicates()
性别年龄身高体重省份成绩月生活费课程兴趣案例教学
序号
1male20.017070.0LiaoNingNaN800.054
2male22.018071.0GuangXi77.01300.034
3maleNaN18062.0FuJian57.01000.024
4male20.017772.0LiaoNing79.0900.044
5male20.0172NaNShanDong91.0NaN55
6male20.017975.0YunNan92.0950.055
7female21.016653.0LiaoNing80.01200.045
8female20.016247.0AnHui78.01000.044
10male19.016976.0HeiLongJiang88.01100.055

3.5 数据规整化

3.5.1 数据合并

应用场景

同一实体的数据来自不同的业务系统

◆  学生的基本信息来自教务系统

◆  学生刷卡数据来自一卡通系统

相同实体的多个数据集

◆  案例3-1中反馈数据存放在5张Excel表中

数据合并可分为两种处理方式

◆  行数据追加
    原数据的列与新增数据的列完全相同
    轴向连接:concat()函数

◆  列数据连接:merge()函数

例3-11 将新同学的信息添加到学生基本信息中

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

#定义两个DataFrame对象存储两个表的数据

colname = ['学号','姓名','专业']
data1 = [['202003101','赵成','软件工程'], ['202005114','李斌丽','机械制造'], ['202009111','孙武一','工业设计']]
stu1 = DataFrame(data1, columns=colname)
stu1
学号姓名专业
0202003101赵成软件工程
1202005114李斌丽机械制造
2202009111孙武一工业设计
data2 = [ ['202003103','王芳','软件工程'], ['202005116','袁一凡','工业设计'] ]
stu2 = DataFrame( data2, columns=colname )   
stu2
学号姓名专业
0202003103王芳软件工程
1202005116袁一凡工业设计
stua = pd.concat([stu1, stu2], axis=0) # axis=0,表示按行进行数据追加
stua
学号姓名专业
0202003101赵成软件工程
1202005114李斌丽机械制造
2202009111孙武一工业设计
0202003103王芳软件工程
1202005116袁一凡工业设计

列数据连接
在这里插入图片描述

参数how的四种合并方式

1)inner:内连接,拼接两个数据对象中键值交集的行,其余忽略
2)outer:外连接,拼接两个数据对象中键值并集的行
3)left:左连接,取出x的全部行,拼接y中匹配的键值行。
4)right:右连接,取出y的全部行,拼接x中匹配的键值行。 

2、3或4种合并方法,当某列数据不存在则自动填充NaN

例3-12 根据一卡通刷卡记录,分析各专业学生上图书馆的习惯,将教务数据表与刷卡信息表拼接起来

cardcol = ['ID','刷卡地点','刷卡时间','消费金额']
data3 = [ ['202003101','一食堂','20180305 1145',14.2], ['104574','教育超市','20180307 1730',25.2],['202003103','图书馆','20180311 1823'],['202005116','图书馆','20180312 0832'],['202005114','二食堂','20180312 1708',12.5],['202003101','图书馆','20180314 1345']]
card = DataFrame( data3, columns=cardcol )   #创建一卡通数据对象
card
ID刷卡地点刷卡时间消费金额
0202003101一食堂20180305 114514.2
1104574教育超市20180307 173025.2
2202003103图书馆20180311 1823NaN
3202005116图书馆20180312 0832NaN
4202005114二食堂20180312 170812.5
5202003101图书馆20180314 1345NaN
stua
学号姓名专业
0202003101赵成软件工程
1202005114李斌丽机械制造
2202009111孙武一工业设计
0202003103王芳软件工程
1202005116袁一凡工业设计
# 采用左连接,忽略非学生记录
# 对应左边表格有的记录,右边表格没有的记录补空,右边表格多的记录丢弃

t = pd.merge(stua, card, how='left', left_on='学号',right_on ='ID')
t
学号姓名专业ID刷卡地点刷卡时间消费金额
0202003101赵成软件工程202003101一食堂20180305 114514.2
1202003101赵成软件工程202003101图书馆20180314 1345NaN
2202005114李斌丽机械制造202005114二食堂20180312 170812.5
3202009111孙武一工业设计NaNNaNNaNNaN
4202003103王芳软件工程202003103图书馆20180311 1823NaN
5202005116袁一凡工业设计202005116图书馆20180312 0832NaN
t[t['刷卡地点']=='图书馆']
学号姓名专业ID刷卡地点刷卡时间消费金额
1202003101赵成软件工程202003101图书馆20180314 1345NaN
4202003103王芳软件工程202003103图书馆20180311 1823NaN
5202005116袁一凡工业设计202005116图书馆20180312 0832NaN
# 右链接,对应右边表格有的记录,左边表格没有的记录补空,左边表格多的记录丢弃
pd.merge(stua, card, how='right', left_on='学号', right_on='ID')
学号姓名专业ID刷卡地点刷卡时间消费金额
0202003101赵成软件工程202003101一食堂20180305 114514.2
1202003101赵成软件工程202003101图书馆20180314 1345NaN
2NaNNaNNaN104574教育超市20180307 173025.2
3202003103王芳软件工程202003103图书馆20180311 1823NaN
4202005116袁一凡工业设计202005116图书馆20180312 0832NaN
5202005114李斌丽机械制造202005114二食堂20180312 170812.5

在这里插入图片描述

# 内链接,保存两个表格都有的记录,不论哪个表格没有的记录都去掉,找交集
pd.merge(stua, card, how='inner', left_on='学号', right_on='ID')
学号姓名专业ID刷卡地点刷卡时间消费金额
0202003101赵成软件工程202003101一食堂20180305 114514.2
1202003101赵成软件工程202003101图书馆20180314 1345NaN
2202005114李斌丽机械制造202005114二食堂20180312 170812.5
3202003103王芳软件工程202003103图书馆20180311 1823NaN
4202005116袁一凡工业设计202005116图书馆20180312 0832NaN
# 外连接,求并集
pd.merge(stua, card, how='outer', left_on='学号', right_on='ID')
学号姓名专业ID刷卡地点刷卡时间消费金额
0202003101赵成软件工程202003101一食堂20180305 114514.2
1202003101赵成软件工程202003101图书馆20180314 1345NaN
2202005114李斌丽机械制造202005114二食堂20180312 170812.5
3202009111孙武一工业设计NaNNaNNaNNaN
4202003103王芳软件工程202003103图书馆20180311 1823NaN
5202005116袁一凡工业设计202005116图书馆20180312 0832NaN
6NaNNaNNaN104574教育超市20180307 173025.2

3.5.2 数据排序

Series和DataFrame 都支持排序

◆  按照列数据值排序
◆  按照列数据生成排名

3.5.2.1 值排序

在这里插入图片描述

例3-13:从文件studentsInfo.xlsx的“Group3”表单中读取数据,对“成绩”进行排序分析。

# 读取文件
stuinfo = pd.read_excel('data/studentsInfo.xlsx', index_col=0)
stuinfo
性别年龄身高体重省份成绩月生活费课程兴趣案例教学
序号
1male20.017070.0LiaoNingNaN800.054
2male22.018071.0GuangXi77.01300.034
3maleNaN18062.0FuJian57.01000.024
4male20.017772.0LiaoNing79.0900.044
5male20.0172NaNShanDong91.0NaN55
6male20.017975.0YunNan92.0950.055
7female21.016653.0LiaoNing80.01200.045
8female20.016247.0AnHui78.01000.044
9female20.016247.0AnHui78.01000.044
10male19.016976.0HeiLongJiang88.01100.055
# 填充缺失值
stuc = stuinfo.fillna(method='bfill')
stuc
性别年龄身高体重省份成绩月生活费课程兴趣案例教学
序号
1male20.017070.0LiaoNing77.0800.054
2male22.018071.0GuangXi77.01300.034
3male20.018062.0FuJian57.01000.024
4male20.017772.0LiaoNing79.0900.044
5male20.017275.0ShanDong91.0950.055
6male20.017975.0YunNan92.0950.055
7female21.016653.0LiaoNing80.01200.045
8female20.016247.0AnHui78.01000.044
9female20.016247.0AnHui78.01000.044
10male19.016976.0HeiLongJiang88.01100.055
# 按照单列排序
stuc.sort_values(by='成绩', ascending=False).loc[:, '成绩']
序号
6     92.0
5     91.0
10    88.0
7     80.0
4     79.0
8     78.0
9     78.0
1     77.0
2     77.0
3     57.0
Name: 成绩, dtype: float64

指定多个列排序,如:by=[‘成绩’, ‘年龄’],先按“成绩”排序,若某些行的“成绩”相同,这几行再按“年龄”排序

# 按照多列排序,可以看1,2两位学生
stuc.sort_values(by=['成绩', '年龄'], ascending=False)
性别年龄身高体重省份成绩月生活费课程兴趣案例教学
序号
6male20.017975.0YunNan92.0950.055
5male20.017275.0ShanDong91.0950.055
10male19.016976.0HeiLongJiang88.01100.055
7female21.016653.0LiaoNing80.01200.045
4male20.017772.0LiaoNing79.0900.044
8female20.016247.0AnHui78.01000.044
9female20.016247.0AnHui78.01000.044
2male22.018071.0GuangXi77.01300.034
1male20.017070.0LiaoNing77.0800.054
3male20.018062.0FuJian57.01000.024

3.5.2.2 排名

排名给出每行的名次

定义等值数据的处理方式,如并列名次取最小值或最大值,也可以取均值。

在这里插入图片描述

# 相同值设置为最小值
stuc['成绩排名'] = stuc['成绩'].rank(method='min', ascending=False)
stuc[['成绩','成绩排名']]
成绩成绩排名
序号
177.08.0
277.08.0
357.010.0
479.05.0
591.02.0
692.01.0
780.04.0
878.06.0
978.06.0
1088.03.0
# 相同值设置为最大值
stuc['成绩排名'] = stuc['成绩'].rank(method='max', ascending=False)
stuc[['成绩','成绩排名']]
成绩成绩排名
序号
177.09.0
277.09.0
357.010.0
479.05.0
591.02.0
692.01.0
780.04.0
878.07.0
978.07.0
1088.03.0
# 相同值设置为平均值,书本上写的是mean,应该是打印错误,得是average
# 更多参数详解可参考 https://juejin.cn/post/6979877027385966622

stuc.loc[3:5, '成绩'] = 77
stuc['成绩排名'] = stuc['成绩'].rank(method='average', ascending=False)
stuc[['成绩','成绩排名']]
成绩成绩排名
序号
177.08.0
277.08.0
377.08.0
477.08.0
577.08.0
692.01.0
780.03.0
878.04.5
978.04.5
1088.02.0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值