欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

Python数据分析入门笔记6——数据清理案例练习

时间:2023-08-19
系列文章目录

Python数据分析入门笔记1——学习前的准备
Python数据分析入门笔记2——pandas数据读取
Python数据分析入门笔记3——数据预处理之缺失值
Python数据分析入门笔记4——数据预处理之重复值
Python数据分析入门笔记5——数据预处理之异常值

Python数据分析入门笔记

系列文章目录前言一、数据获取二、数据清理

1、缺失值处理2、重复值处理3、异常值处理 声明


前言

案例资源文件:点击下载二手房数据表格
二手房数据存在一些问题。要求使用pandas库对这组数据进行清理,具体步骤如下:

检测缺失值,一旦发现缺失值就将其删除。检测重复值,一旦发现重复值就将其删除。检测二手房数据“单价(元/平方米)”列的异常值,一旦确定是真异常值就将其删除。
一、数据获取

打开excel文件,探索整体数据,直接观测。
文件部分数据如图:

可以很明显的看到,“地铁”列存在缺失数据,其他问题暂时看不出来。

首先使用pandas的read_excel方法,读取数据

可以很明显的看到,“地铁”列的数据缺失,默认用NaN值来填充。

数据获取之后,可以用info()函数来查看二手房数据的摘要信息。

可以看出,二手房数据各列非空值的数量以及数据类型, 还能看到除了“地铁”列外,小区名称也有缺失。

二、数据清理

    由于二手房数据中可能包含缺失值、重复值和异常值,下面分别进行处理。

1、缺失值处理

    缺失数据列:地铁,小区名称。
    结合实际情况分析,小区的地理位置可能远离地铁,因此“地铁”列的缺失值无需处理。这里只需要删除“小区名称”列中的缺失值即可。
    用dropna()方法来删除“小区名称”列包含缺失值的一行数据。

# 删除小区名称列的缺失值second_hand_house = second_hand_house.dropna(subset=['小区名称'])second_hand_house

执行结果:

可以看出,删除缺失值后,二手房数据剩余1057行,比之前减少了一行

2、重复值处理

使用duplicated()方法先检测二手房数据中是否有重复值。

# 对删除缺失值后的数据进行重复值检测second_hand_house.duplicated()

执行结果如下:

由于被检测的数据量较大,无法直接看出都有哪些行被标记为了True,所以需要加个筛选,筛选出结果对象中值为True的值,即重复项。

# 显示二手房数据中的重复项second_hand_house[second_hand_house.duplicated().values == True]

然后删除重复项

# 删除重复值,并对索引重新排序second_hand_house = second_hand_house.drop_duplicates(ignore_index=True)second_hand_house

执行结果如下:

可以看出,删除重复数据以后,还剩999条。

3、异常值处理

    结合实际逻辑,制定方案,对关键列进行检查。
    缺失值和重复值处理完之后,还需检测“单价”列中是否包含异常值。
    因为每个楼盘的地理位置、配套设施、以及开盘时间各不相同,所以每个小区的出售价格也不相同,无法直接对“单价”列进行异常值检测。
    为了准确地检测异常值,这里先按小区名称对数据进行分组,再分别对每个分组进行异常值检测。
以“翡翠城四期”小区为例,使用箱型图检测该小区“单价”数据是否存在异常值。

from matplotlib import pyplot as plt# 设置中文显示plt.rcParams['font.sans-serif'] = ['SimHei']# 筛选小区名称为“翡翠城四期”的数据estate = second_hand_house[second_hand_house['小区名称'].values == '翡翠城四期' ]box = estate.boxplot(column='单价(元/平米)')plt.show()


从图上可以看到,箱型图中有一个异常值。
对于被检测出来的异常值,我们需要先查看具体是哪些数据,之后再决定是否删除。
定义一个用于获取异常值及其索引的函数box_outliers():

def box_outliers(ser): # 对需要检测的数据集进行排序 new_ser = ser.sort_values() # 判断数据的总数量是奇数还是偶数 if new_ser.count() % 2 == 0: # 分别计算Q3、Q1、IQR Q3 = new_ser[int(len(new_ser) / 2):].median() Q1 = new_ser[:int(len(new_ser) / 2)].median() elif new_ser.count() % 2 != 0: Q3 = new_ser[int((len(new_ser)-1) / 2):].median() Q1 = new_ser[:int((len(new_ser)-1) / 2)].median() IQR = round(Q3 - Q1, 1) rule = (round(Q3+1.5 * IQR, 1) ser) index = np.arange(ser.shape[0])[rule] # 获取包含异常值的数据 outliers = ser.iloc[index] return outliers

依次获取每个小区数据,并使用box_outliers()函数检测数据中是否包含异常值,返回数据中的异常值及其对应的索引。

# 保存异常值索引outliers_index_list = []# 遍历所有小区名称for i in set(second_hand_house['小区名称']):# 筛选小区名称为i的所有二手房数据集 estate = second_hand_house[second_hand_house['小区名称'].values == i] # 调用箱型图函数,检测小区名称为i的数据中单价列是否有异常值,返回异常值行索引列表outliers_index outliers_index = box_outliers(estate['单价(元/平米)']) # 只要有异常值,即异常值列表长度不为零 if len(outliers_index) != 0: # 将异常值的索引添加到定义的列表中 outliers_index_list.append(outliers_index.index.tolist())# 此时的outliers_index_list为嵌套列表,将其转换为单层列表outliers_index_single_li = sum(outliers_index_list, [])

根据以上获得的索引,可访问含有异常值的数据:

second_hand_house.loc[[i for i in outliers_index_single_li]]


经检查,这些异常值我们选择调用drop()方法直接删掉。

second_hand_house.drop(0)


声明

本文资源来自人民邮电出版社的《Python数据预处理》,作者是黑马程序员。

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。