引言
先來一個腦筋急轉彎活躍一下枯燥工作日常,問:“什么東西越洗越黑?” 有沒有猜到的?猜不到我告訴你吧! 答案是“煤球”。那么這個腦機急轉彎跟我們要討論的話題有沒有關系呢?
嗯是的,還是沾點兒邊兒的。
我們經常在項目上生產線之前,肯定會先在測試服上進行測試,測試之前肯定會將垃圾數據清理掉,防止臟數據影響我們正常的測試邏輯。
在我們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 pddf = 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 pddf = 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