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

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

Python数据分析入门笔记6——数据清理案例练习 系列文章目录

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数据预处理》,作者是黑马程序员。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5721297.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-18
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存