引言
先来一个脑筋急转弯活跃一下枯燥工作日常,问:“什么东西越洗越黑?” 有没有猜到的?猜不到我告诉你吧! 答案是“煤球”。那么这个脑机急转弯跟我们要讨论的话题有没有关系呢?
嗯是的,还是沾点儿边儿的。
我们经常在项目上生产线之前,肯定会先在测试服上进行测试,测试之前肯定会将垃圾数据清理掉,防止脏数据影响我们正常的测试逻辑。
在我们pyhton语言中,也提供了清理无用数据,进行数据清洗的库Pandas, 确实也用了一下,封装的方法的确挺好用,但也同时碰到了一些问题,接下来分享一下吧。
知道 😮
在正式分享之前,我们得先知道Pandas库是干什么用的?它就是一个主要进行数据读取,数据清理提供方法的这么一个库。至于它的安装方式,非常简单👌,只要电脑安装了Pyhton环境,那么我们就使用cmd小黑屏使用pip进行安装即可。这里大概写一下吧,pip install pandas
。安装完成以后,命令行进行查看是否安装成功python -c "import pandas; print(pandas.__version__)"
。
关于Pandas库是干什么的?如何安装它,我们大概就说这么多,下面将探讨我遇到的数据清洗的问题。
问题 😱
Pandas库给我们提供非常丰富的数据🚿清洗的函数,其中我们用的多的大概就是 dropna() 函数了。
dropna()函数的格式是这样的:DataFrame.dropna(axis=0, how='any', thresh=None, subset=None, inplace=False)。其中axis:哪个轴(这个我们很熟悉了);how:设置整行还是所有;inplace:bool型,如果赋值为True的话,修改的是源数据。
我们浅浅的使用一下,实例代码如下:
"""
@Created on : 2024/5/29 10:56
@creator : er_nao
@File :pandas_06_数据清洗.py
@Description :
"""
import pandas as pd
df = pd.read_csv("../property-data.csv")
print(df)
print('\n')
print(df['NUM_BEDROOMS'])
print('\n')
print(df['NUM_BEDROOMS'].isnull())
print('\n')
# 使用dropna删除包含空数据的行
# 默认情况下,dropna() 方法返回一个新的 DataFrame,不会修改源数据
print('使用dropna删除包含空数据的行')
new_df = df.dropna()
print(new_df.to_string())
print('\n')
print(df.to_string())
# 如果你要修改源数据 DataFrame, 可以使用 inplace = True 参数:
print('\n')
print('使用 inplace = True')
df.dropna(inplace=True)
print(df.to_string())
# 输出结果
# PID ST_NUM ST_NAME OWN_OCCUPIED NUM_BEDROOMS NUM_BATH SQ_FT
# 0 100001000.0 104.0 PUTNAM Y 3 1 1000
# 1 100002000.0 197.0 LEXINGTON N 3 1.5 --
# 2 100003000.0 NaN LEXINGTON N NaN 1 850
# 3 100004000.0 201.0 BERKELEY 12 1 NaN 700
# 4 NaN 203.0 BERKELEY Y 3 2 1600
# 5 100006000.0 207.0 BERKELEY Y NaN 1 800
# 6 100007000.0 NaN WASHINGTON NaN 2 HURLEY 950
# 7 100008000.0 213.0 TREMONT Y 1 1 NaN
# 8 100009000.0 215.0 TREMONT Y na 2 1800
#
#
# 0 3
# 1 3
# 2 NaN
# 3 1
# 4 3
# 5 NaN
# 6 2
# 7 1
# 8 na
# Name: NUM_BEDROOMS, dtype: object
#
#
# 0 False
# 1 False
# 2 True
# 3 False
# 4 False
# 5 True
# 6 False
# 7 False
# 8 False
# Name: NUM_BEDROOMS, dtype: bool
#
#
# 使用dropna删除包含空数据的行
# PID ST_NUM ST_NAME OWN_OCCUPIED NUM_BEDROOMS NUM_BATH SQ_FT
# 0 100001000.0 104.0 PUTNAM Y 3 1 1000
# 1 100002000.0 197.0 LEXINGTON N 3 1.5 --
# 8 100009000.0 215.0 TREMONT Y na 2 1800
#
#
# PID ST_NUM ST_NAME OWN_OCCUPIED NUM_BEDROOMS NUM_BATH SQ_FT
# 0 100001000.0 104.0 PUTNAM Y 3 1 1000
# 1 100002000.0 197.0 LEXINGTON N 3 1.5 --
# 2 100003000.0 NaN LEXINGTON N NaN 1 850
# 3 100004000.0 201.0 BERKELEY 12 1 NaN 700
# 4 NaN 203.0 BERKELEY Y 3 2 1600
# 5 100006000.0 207.0 BERKELEY Y NaN 1 800
# 6 100007000.0 NaN WASHINGTON NaN 2 HURLEY 950
# 7 100008000.0 213.0 TREMONT Y 1 1 NaN
# 8 100009000.0 215.0 TREMONT Y na 2 1800
#
#
# 使用 inplace = True
# PID ST_NUM ST_NAME OWN_OCCUPIED NUM_BEDROOMS NUM_BATH SQ_FT
# 0 100001000.0 104.0 PUTNAM Y 3 1 1000
# 1 100002000.0 197.0 LEXINGTON N 3 1.5 --
# 8 100009000.0 215.0 TREMONT Y na 2 1800
我们可以看到,使用dropna()函数后,虽然会将有空值,NaN,na这些数据所在的行剔除掉🗑,个人认为这样非常的不友好🙅♂️,那么有其他办法不剔除掉吗?答案是有的。
Pandas库还给我们提供了一个fillna函数 我们可以使用它将那些空值,NaN替换让数据变得有意义。
"""
@Created on : 2024/5/29 10:56
@creator : er_nao
@File :pandas_06_数据清洗.py
@Description :
"""
import pandas as pd
df = pd.read_csv("../property-data.csv")
print('源数据')
print(df)
print('\n')
# 使用 mean() 方法计算列的均值并替换空单元格
print('使用fillna')
x = df['ST_NUM'].mean()
df['ST_NUM'].fillna(x, inplace=True)
print(df.to_string())
# 输出结果
# 源数据
# PID ST_NUM ST_NAME OWN_OCCUPIED NUM_BEDROOMS NUM_BATH SQ_FT
# 0 100001000.0 104.0 PUTNAM Y 3 1 1000
# 1 100002000.0 197.0 LEXINGTON N 3 1.5 --
# 2 100003000.0 NaN LEXINGTON N NaN 1 850
# 3 100004000.0 201.0 BERKELEY 12 1 NaN 700
# 4 NaN 203.0 BERKELEY Y 3 2 1600
# 5 100006000.0 207.0 BERKELEY Y NaN 1 800
# 6 100007000.0 NaN WASHINGTON NaN 2 HURLEY 950
# 7 100008000.0 213.0 TREMONT Y 1 1 NaN
# 8 100009000.0 215.0 TREMONT Y na 2 1800
#
#
# 使用fillna
# PID ST_NUM ST_NAME OWN_OCCUPIED NUM_BEDROOMS NUM_BATH SQ_FT
# 0 100001000.0 104.000000 PUTNAM Y 3 1 1000
# 1 100002000.0 197.000000 LEXINGTON N 3 1.5 --
# 2 100003000.0 191.428571 LEXINGTON N NaN 1 850
# 3 100004000.0 201.000000 BERKELEY 12 1 NaN 700
# 4 NaN 203.000000 BERKELEY Y 3 2 1600
# 5 100006000.0 207.000000 BERKELEY Y NaN 1 800
# 6 100007000.0 191.428571 WASHINGTON NaN 2 HURLEY 950
# 7 100008000.0 213.000000 TREMONT Y 1 1 NaN
# 8 100009000.0 215.000000 TREMONT Y na 2 1800
大家可以看到,ST_NUM这一列计算了平均值,并且将之前的NaN也替换成了平均值。但是控制台的打印真的是这样吗?请看下图:
呀~~ 🦆🦆🦆 ,控制台居然有报红,我们程序员看到报红脑子第一个闪现的念头就是报错了。数据清洗还给洗出BUG了?那清洗还有什么意义。
经过分析,这不是报错,而是警告😡! 意思就是我们的写法有问题呗。既然这样,我们就遵从人家的提示,就改吧。
这儿的意思就是让我们改成这种形式,好的。
咿?!神奇呦🧙。果然不爆红了。那么这两种写法到底有什么区别呢?
a写法: df.method({col: value}, inplace=True)
b写法: df[col].method(value, inplace=True)
这其实就是一个链式赋值问题的问题,当使用b写法的时候,Pandas它不知道到底是想在原始DataFrame上进行更改,还是想创建一个副本进行更改,所以就会引发我们控制台的这个异常。
而a写法它通常是对整个DataFrame应用一个方法,同时传入一个列名与值的映射,指定要修改的列和相应的值。
作者:二闹
链接:https://juejin.cn/post/7374243125458649124