pandas数据清洗
pandas
实验目标
实验目标
实验目标
* 任务二:Pandas数据分析实战
* * 【任务目标】
* 【任务步骤】
任务目标
本章目标
任务目标
任务步骤
所需数据和代码
1、预备知识-python核心用法常用数据分析库
概述
Python 以其广泛的应用场景和技术深度成为全球最受欢迎的编程语言之一。其最主要的应用场景之一便是数据处理与分析领域。在 Python 提供的各种数据分析工具集合中, Pandas 是 Python 中广为人知并广泛应用的数据分析库之一, 广泛应用于多个技术领域如数据挖掘与机器学习等场景中。借助 Pandas 工具, 我们能够轻松完成从 Excel 文件、文本文件以及多种数据库系统中导入数据的基本操作, 并通过其强大的功能特点执行复杂的清洗任务, 进行过滤操作以及多维度的数据透视表生成, 同时还可以利用其绘图功能快速生成折线图、柱状图以及饼图等多种形式的数据可视化图表。Pandas 在功能上不仅实现了对大规模文件集的自动化处理能力, 更能够在一定程度上超越传统 Excel 功能, 同时具备更为强大的扩展性和灵活性。
本次实验旨在通过实践操作全面讲解pandas数据分析库的基础知识与基本操作步骤;通过案例演示帮助大家在短时间内高效地掌握Python数据分析库pandas的核心功能与实际应用方法;并为其后续项目开发奠定基础
实验环境
- Python 3.7
- PyCharm
任务一:环境安装与配置
【实验目标】
本实验的核心任务是搭建本次实验的运行环境,在Windows操作系统中完成本次实验所需的配置工作。本实验所需软件工具包括PyCharm+Python 3.7版本。
【实验步骤】
1、安装Python 3.7
2、安装Pycharm
3、安装jupyter、pandas、numpy、notebook
打开CMD,并输入以下命令,安装jupyter、notebook、pandas和numpy
pip install jupyter notebook pandas numpy
安装完成后会有类似如下文字提示:

以上步骤完成后,实验环境配置工作即已完成,关闭CMD窗口
任务二:Pandas数据分析实战
【任务目标】
本任务的核心目标在于运用pandas模块在实际操作环境中进行数据分析实践,在这一过程中帮助我们在实践中掌握pandas的一系列功能或特性。
- 准备工作流程如下:
- 数据审查:对原始数据进行全面检查。
- 缺失值处理:实施方法以填补或移除缺失的数据。
- 数据填补:采用策略来设定适当默认值。
- 数据清理:去除包含不完整记录的行或字段。
- 标准化处理:统一所有数据格式。
- 字段重塑:重新命名字段名称以提高可读性。
- 结果存储:保存最终整理好的数据集。
【任务步骤】
1、打开CMD,执行如下命令,开启jupyter
jupyter notebook
成功执行以上命令后,系统将自动打开默认浏览器,如下图所示:

成功打开浏览器后,按如下流程创建 notebook 文件

对新建notebook进行重命名操作


2、notebook 文件新建完成后,接下来在新建的 notebook 中编写代码
导入 Pandas 到我们的代码中,代码如下
import pandas as pd
Shift + Enter
Shift + Enter
Shift + Enter
小提示:在完成所有编码后,请确保按下【Shift + Enter
加载数据集,代码如下:
data = pd.read_csv('./data/movie_metadata.csv')
3、检查数据
查看数据集前5行
data.head()
运行结果如下图所示:

我们可以通过前面提到的Pandas工具来查看数据;另外一种方法是借助传统的Excel软件来观察数据
该库提供了多种方法来处理数据的索引操作。这些方法不仅能够对数据进行行索引和列标签的定位(slicing),同样支持基于行号和列号的位置定位(dicing)。让我们简单介绍一下这些方法的基本用法:
- 获取某一列的基础统计信息,请执行 `data[column_name].describe()``。
- 从数据集中提取特定的一列,请执行 `data['column_name']``。
- 提取某列为某一范围的数据,请执行 `data['columns_name'][:n]``。
- 从数据集中获取多列的信息,请执行 `data[['column1', 'column2']]``。
- 根据特定条件筛选数据,请执行
data[data['column_name'], condition].
4、处理缺失数据
缺失数据是最常见的问题之一。产生这个问题有以下原因:
- 从来没有填正确过
- 数据不可用
- 计算错误
不论原因何在,只要存在缺失值的情况,就必然导致后续分析出现问题.下面介绍几种处理缺失数据的方法:
- 为缺失数据赋值默认值
- 去掉/删除缺失数据行
- 去掉/删除缺失率高的列
4.1、添加默认值
使用空字符串来填充country字段的空值
data.country= data.country.fillna('')
使用均值来填充电影时长字段的空值
data.duration = data.duration.fillna(data.duration.mean())
4.2、删除不完整的行
data.dropna()
运行结果显示为了节省篇幅仅列出部分数据

由上图可以看出,由于第4行数据存在缺失值,因此被删除
提示说明:dropna操作不会直接修改原始数据的数据值;它会创建一个副本用于后续的操作处理,并因此确保了原始数据并未发生任何变化。
删除一整行的值都为 NA:
data.dropna(how='all')// all 这一行全部为空才会被删除// any 一行中任意一个为空,就会被删除
运行结果如下:

根据图表所示,在执行约束条件时(即删除所有全为空的数据行),即使某些数据不符合该约束条件的信息来源依然会保留下。
我们还可以设置一些条件来过滤数据,在如下的代码段中筛选出具有最少n个有效数据的数据行
data.dropna(thresh=5)
运行结果如下:

也可指定需要删除缺失值的列
为了便于分析这一情况, 我们将重点考察 title_year 列中的数据特征: 然后评估该列中的缺失数据情况.
data['title_year'].isnull().value_counts()
结果如下:

由上图可知,title_year 这一列中存在108个缺失值
接下来查看 title_year 删除完缺失值后的情况
dropna(subset=[‘title_year’]),丢弃’title_year’这一列中有缺失值的行
new_data = data.dropna(subset=['title_year'])new_data['title_year'].isnull().value_counts()
上面的 subset 参数支持我们选择想要检查的列。如果是多个列,则可以以列表形式存在作为参数。
运行结果如下:

4.3、删除不完整的列
我们可以将上述操作应用于列中。仅在代码实现时指定axis参数为1即可。这表示我们的操作专注于列而非行。(我们在处理行的情况时已经使用了axis=0,这是因为如果不传axis参数,默认情况下axis设为0)
删除一整列为 NA 的列:
data.dropna(axis=1, how='all')
运行结果如下:

删除任何包含空值的列:
data.dropna(axis=1,how='any')

这里也可以使用像上面一样的 threshold 和 subset
5、规范化数据类型
加载数据集时指定字段数据类型dtype={‘title_year’:str})
data = pd.read_csv('./data/movie_metadata.csv', dtype={'title_year':str})
这相当于向Pandas说明该数据框中的‘duration’列的数据类型为数值型。检查加载完成后各数据列的类型情况
data.info()
运行结果如下:

object 即代表数据类型为字符串类型
6、必要的变换
人工录入的数据可能都需要进行一些必要的变换,例如:
- 错别字
- 英文单词时大小写的不统一
- 输入了额外的空格
首先查看 movie_title 列数据
data.movie_title
结果如下:

我们数据中所有的 movie_title 改成大写:
data['movie_title'].str.upper()
结果如下:

同样的,我们可以去掉末尾余的空格:
data['movie_title'].str.strip()
运行结果如下:

7、重命名列名
我们需要进行重新赋值才可以:
data = data.rename(columns={'title_year':'release_date', 'movie_facebook_likes':'facebook_likes'})
查看重命名后的数据列名称
data.info()
输出结果如下:

8、保存结果
在完成数据清洗后, 通常会将结果以CSV格式保存下来, 以便后续其他程序能方便地处理这些数据. 同样地,Pandas提供了非常方便的方法
data.to_csv('./data/cleanfile.csv',encoding='utf-8')
查看 /home/student/data 目录内容如下,新增保存的 cleanfile.csv 文件

2、预备知识-python核心用法常用数据分析库(下)
实验环境
- Python 3.7
- Pycharm
任务二:Pandas数据分析实战-1
【任务目标】
本任务的核心目标是以pandas为基础开展数据分析实践,在实践中向大家展示其一并具备的功能。
- 了解数据
- 分析数据问题
- 清洗数据
- 整合代码
【任务步骤】
1、准备工作
打开CMD窗口后,执行如下命令,打开jupyter notebook编辑器
jupyter notebook
成功执行以上命令后,系统将自动打开默认浏览器,如下图所示:

成功打开浏览器后,按如下流程创建 notebook 文件

对新建notebook进行重命名操作


2、notebook 文件新建完成后,接下来在新建的 notebook 中编写代码
- 了解数据
在处理所有数据之前,在此阶段我们的首要任务就是掌握这些信息表中的内容,并弄清楚它们各自的作用。为了深入分析这些信息表中的内容,在此阶段我们特别关注每一列和每一行所代表的数据类型以及各个条目之间的关联。通过这样的分析过程……为后续的数据清洗工作打下基础。
在本次研究中,我们采用了 patient_heart_rate.csv 文件作为数据源。该数据集规模较小,并提供了清晰的概览。该数据采用 csv 格式进行存储,并记录了参与者在各个时间段的心率变化情况。详细信息包括年龄、体重、性别以及各个时间段的心率数值。
- 加载数据即查看数据集
import pandas as pd
df = pd.read_csv('data/patient_heart_rate.csv')
df.head()
运行结果如下:

分析数据问题
未设置表头
3、清洗数据
3.1、 没有列头
如果数据没有预设的列头,则Pandas在读取CSV时支持自定义列名的参数设置。我们可以通过手动指定列名来解析CSV文件。
import pandas as pd
column_names= ['id', 'name', 'age', 'weight','m0006',
'm0612','m1218','f0006','f0612','f1218']
df = pd.read_csv('data/patient_heart_rate.csv', names = column_names)
df.head()
运行结果如下:

上文显示我们自定义了列表头。实际上,在这次读取csv时增加了names参数(names=column_names),这正是为了告知Pandas使用我们提供的列名。
4、一个列有多个参数
从数据中可以看出Name字段包含两个参数Firstname和Lastname为了实现数据整洁的目标我们将Name字段拆分为FirstName和LastName
使用 str.split(expand=True),将列表拆成新的列,再将原来的 Name 列删除
df[['first_name','last_name']] = df['name'].str.split(expand=True)
df.drop('name', axis=1, inplace=True)
df.head()
运行结果如下:

5、列数据的单位不统一
经过有意识地审视数据集后会注意到Weight列的计量单位存在差异。其中一些单元格记录的是kgs(公斤),另一些单元格则记录的是lbs(磅)。
// pandas 的 apply() 函数可以作用于 Series 或者整个 DataFrame,功能也是自动遍历整个 Series 或者 DataFrame
lbs_weight_s = df[df.weight.str.contains("lbs").fillna(False)]['weight']
lbs_weight_s = lbs_weight_s.apply(lambda lbs: "%.2fkgs" % (float(lbs[:-3])/2.2) )
df.loc[lbs_weight_s.index,'weight'] = lbs_weight_s
运行结果如下:

6、缺失值处理
在数据集中存在一些未记录的年龄、体重和心率数值。我们也面临着数据清洗中最常见的核心挑战——数据缺失问题。通常由于未能收集到相关数据而发生这种情况。我们可以通过咨询行业专家来获取建议。典型的处理缺失数据的方法:
- 删除缺失数据的记录
- 使用合法初始值替代:
数值型字段可用 0 替代,
字符串字段可用空字符串" "替代。 - 计算该列的数据平均值。
- 提取出该列中出现频率最高的数值项。
- 若有与数据接收方沟通的机会,则可共同排查问题并寻求解决方案。
7、重复数据处理
有时候在某个特定的数据集中可能存在一些重复的内容;运行下面的代码块以查看前十个记录。
df.head(10)
运行结果如下:

观察以上结果,可以发现在我们的数据集中也存在重复的数据,如下

首先我们对数据进行核查以确定是否存在重复记录。如果有重复记录则可以调用Pandas模块中的drop_duplicates()函数来去除这些多余的数据项
df.drop_duplicates(['first_name','last_name'],inplace=True)
df.head(10)
运行结果如下:

删除weight字段重复的数据
df.drop_duplicates(['weight'],inplace=True)
df.head(10)
运行结果如下

8、 非ASCII 字符
在数据集中 Fristname 和 Lastname 有一些非 ASCII 的字符。
处理非 ASCII 数据方式有多种
- 删除
- 替换
- 仅仅提示一下
我们使用删除的方式:
df['first_name'].replace({r'[^\x00-\x7F]+':''}, regex=True, inplace=True)df['last_name'].replace({r'[^\x00-\x7F]+':''}, regex=True, inplace=True)df.head()
运行结果如下:

9、有些列头应该是数据,而不应该是列名参数
一些列标题由性别属性以及时间段标识组成,在数据收集阶段进行了行列转换处理,并遵循了固定的命名规范。这些数据项应被拆分为性别属性(m,f)以及小时级别的时间段标识(00-06, 06-12, 12-18)。
sorted_columns = ['id','age','weight','first_name','last_name']
df = pd.melt(df,
id_vars=sorted_columns,
var_name='sex_hour',
value_name='puls_rate')
df = df[df.puls_rate != '-'].dropna()
df = df.sort_values(['id','first_name','']).reset_index()
def split_sex_date(sex_hour):
sex = sex_hour[:1]
if 'f' == sex:
sex = '女'
elif 'm' == sex:
sex = '男'
hour = sex_hour[1:]
return pd.Series([sex,hour])
df[['sex','hour']] = df.sex_hour.apply(split_sex_date)
df.drop('sex_hour',axis=1)
运行结果如下:

任务三:Pandas数据分析实战-2
【任务目标】
本任务的核心目标是通过实际操作带领学习者认识并掌握pandas模块的基本功能:借助真实场景的数据分析实践,帮助学习者深入了解并熟练运用pandas模块的核心功能。
- 日期的处理
- 字符编码的问题
【任务步骤】
任务一
任务一
任务一

2、预览数据
这次我们使用 Artworks.csv,我们选取 100 行数据来完成本次内容。具体步骤:
- 导入Pandas
- 读取 csv 数据到 DataFrame(要确保数据已经下载到指定路径)
Pandas 是一个集成模块,其核心功能包括数据分析与操作,并支持大量高效的数据存储格式.该模块提供了一个称为 DataFrame 的数据呈现形式,能够高效处理数据并进行各种计算操作.通过调用 DataFrame,我们能够方便快捷地查看和评估数据集中的信息.
import pandas as pd
df = pd.read_csv('./data/Artworks.csv').head(100)
df.head(10)
运行结果如下:

2、统计日期数据
我们对 Date 列的数据进行了详细审视,并发现其中有部分数据代表的是时间段(如1976至1977),而非单一具体年份。由于这些时间段的数据难以直接转化为直观的时间点坐标,在绘图时需要特别处理以确保结果准确呈现。为了更好地分析这些数据分布情况,我们现在调用了Pandas中的value_counts()方法进行统计
首先,选择要统计的列,并调用 value_counts():
df['Date'].value_counts()
运行结果如下:

3、日期数据问题
日期字段的数据中除了年份字段属于正常范围外其余三种字段的格式存在异常我们计划对这些异常情况进行详细分析并逐一排查原因
- 该时间段(期间)详细说明了具体的时间段。
- 该预测(预测)进一步指明了大致的时间框架。
- 该情况缺少明确的数据信息(Missing data情况: (Unknown))
- 该部分缺乏有意义的数据支持 (n.d.)
接下来我们将解决所有相关的问题,并借助Pandas库将这些不规则的数据转化为统一数据格式。
虽然问题一和二也仅有数据存在但其格式上存在不足之处而问题三和四实际上不具备有效数值特征
处理问题一
问题一的数据均涉及两个不同年份的时间范围。我们可以从中选取一个特定的年份来作为清洗后数据的基础。为了简化处理过程, 我们将采用起始年的数值, 因为这个数值是一个完整的四位数, 若采用结束年的数值则需补足前面两位
首先, 我们需要获取第一个问题的数据, 这样我们才能将其重新设置. 为了确保其他数据不得被修改, 请特别注意这些数据可能已经是格式化的了, 并且也可能是我们后续要处理的内容.
我们计划处理的时间范围内的数据,在这些数据中包含特定的减号符号。因此,在进行数据处理之前,我们可以利用这个特定的字符串来筛选所需的数据。接着使用split()方法,并以减号分隔这些数据,并将其第一个部分作为最终的结果
代码如下
row_with_dashes = df['Date'].str.contains('-').fillna(False)
for i, dash in df[row_with_dashes].iterrows():
df.at[i,'Date'] = dash['Date'][0:4]
df['Date'].value_counts()
运行结果如下:

处理问题二
问题二的数据反映出数据本身的不确定性;它是一个基于估算的一个时间段;因此我们需要将其转化为年份数值;其显著特征在于所有数据都包含字母"c";这样我们便可以通过这一共同特征筛选出需要转换的数据
row_with_cs = df['Date'].str.contains('c').fillna(False)
for i,row in df[row_with_cs].iterrows():
df.at[i,'Date'] = row['Date'][-4:]
df[row_with_cs]
运行结果如下:

处理问题三四
将这问题三四的数据赋值成初始值 0
df['Date'] = df['Date'].replace('Unknown','0',regex=True)
df['Date'] = df['Date'].replace('n.d.','0',regex=True)
df['Date']
运行结果如下:

4、附:完成代码
注意:完整代码中删除了数据展示部分
import pandas as pd
df = pd.read_csv('../data/Artworks.csv').head(100)
df.head(10)
df['Date'].value_counts()
row_with_dashes = df['Date'].str.contains('-').fillna(False)
for i, dash in df[row_with_dashes].iterrows():
df.at[i,'Date'] = dash['Date'][0:4]
df['Date'].value_counts()
row_with_cs = df['Date'].str.contains('c').fillna(False)
for i,row in df[row_with_cs].iterrows():
df.at[i,'Date'] = row['Date'][-4:]
df['Date'].value_counts()
df['Date'] = df['Date'].replace('Unknown','0',regex=True)
df['Date'] = df['Date'].replace('n.d.','0',regex=True)
df['Date'].value_counts()
