日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

pandas用众数填充缺失值_7步搞定数据清洗-Python数据清洗指南

發(fā)布時間:2023/12/2 python 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 pandas用众数填充缺失值_7步搞定数据清洗-Python数据清洗指南 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

臟數(shù)據(jù)就是在物理上臨時存在過,但在邏輯上不存在的數(shù)據(jù)。

數(shù)據(jù)清洗是整個數(shù)據(jù)分析過程的第一步,就像做一道菜之前需要先擇菜洗菜一樣。數(shù)據(jù)分析師經(jīng)常需要花費大量的時間來清洗數(shù)據(jù)或者轉(zhuǎn)換格式,這個工作甚至會占整個數(shù)據(jù)分析流程的80%左右的時間。

在這篇文章中,我嘗試簡單地歸納一下用Python來做數(shù)據(jù)清洗的7步過程,供大家參考。

一、數(shù)據(jù)預(yù)處理

一、數(shù)據(jù)預(yù)處理

部署環(huán)境,導(dǎo)入分析包和數(shù)據(jù)

#導(dǎo)入數(shù)據(jù)分析包

import pandas as pdimport numpy as np

#導(dǎo)入csv數(shù)據(jù)

#dtype = str,最好讀取的時候都以字符串的形式讀入,不然可能會使數(shù)據(jù)失真#比如一個0010008的編號可能會讀取成10008fileNameStr = './Actual transactions from UK retailer.csv'DataDF = pd.read_csv(fileNameStr,encoding = "ISO-8859-1",dtype = str)# encoding = "ISO-8859-1" -- 用什么解碼,一般會默認系統(tǒng)的編碼,如果是中文就用 "utf-8"DataDF = pd.read_csv(fileNameStr,encoding = "utf-8",dtype = str)

2. 嘗試去理解這份數(shù)據(jù)集

我們可以通過對數(shù)據(jù)集提問來判斷這份數(shù)據(jù)能不能滿足解答我們的問題,數(shù)據(jù)是否干凈需不需要進一步處理,問題包括但不限于:數(shù)據(jù)集多少數(shù)據(jù)?包含了什么字段?字段格式是什么?字段分別代表什么意義字段之間的關(guān)系是什么?可以用做什么分析?或者說能否滿足了對分析的要求?有沒有缺失值;如果有的話,缺失值多不多?現(xiàn)有數(shù)據(jù)里面有沒有臟數(shù)據(jù)?尤其需要注意人工輸入的數(shù)據(jù),經(jīng)常會出現(xiàn)名稱寫錯,多輸入空格等等的情況

3. 下面我們就結(jié)合代碼來看一下數(shù)據(jù)

#1 從宏觀一點的角度去看數(shù)據(jù):查看dataframe的信息

DataDF.info()

也可以用這兩條來看:

#1.1查看每一列的數(shù)據(jù)類型

DataDF.dtypes#1.2有多少行,多少列DataDF.shape

# 2.檢查缺失數(shù)據(jù)

# 如果你要檢查每列缺失數(shù)據(jù)的數(shù)量,使用下列代碼是最快的方法。# 可以讓你更好地了解哪些列缺失的數(shù)據(jù)更多,從而確定怎么進行下一步的數(shù)據(jù)清洗和分析操作。DataDF.isnull().sum().sort_values(ascending=False)

# 3.是抽出一部分數(shù)據(jù)來,人工直觀地理解數(shù)據(jù)的意義,盡可能地發(fā)現(xiàn)一些問題

DataDF.head()

可以看到:

1)Country和UnitPrice都出現(xiàn)了NaN值,需要去掉

2)InvoiceDate的時間出現(xiàn)具體時分,可以刪去

3)Description大概率是人工填寫的數(shù)據(jù),一般都會有比較多格式問題。

猜測會存在有標點符號摻雜/大小寫不一致等問題,所以進一步這些人工填寫數(shù)據(jù)的去重項拎出來研究一下

# 查看這個商品名稱的去重項

DataDF['Description'].unique()

# 設(shè)置輸出全部的內(nèi)容

# threshold就是設(shè)置超過了多少條,就會呈現(xiàn)省略#(比如threshold=10的意思是超過10條就會省略)np.set_printoptions(threshold=np.inf)

發(fā)現(xiàn)有很多空格的問題

根據(jù)第一步數(shù)據(jù)預(yù)處理后,整理一下該數(shù)據(jù)集有下列問題需要處理:

1)調(diào)整數(shù)據(jù)類型:由于一開始用到了str來導(dǎo)入,打算后期再更換格式,需要調(diào)整數(shù)據(jù)類型。

2)修改列名:該數(shù)據(jù)的名稱不易于理解,需要改列名

3)選擇部分子集:因為有部分列在數(shù)據(jù)分析中不需要用到

4)可能存在邏輯問題需要篩選:比如Unit Price為負

5)格式一致化:Description可能會存在有標點符號摻雜/大小寫不一致/空格重復(fù)出現(xiàn)等問題

6)消滅空值:CustomerID、Description、Country和UnitPrice都出現(xiàn)了NaN值,需要去掉

于是下面就開始后續(xù)的數(shù)據(jù)清洗6步

二、調(diào)整數(shù)據(jù)類型

數(shù)據(jù)類型調(diào)整前

#字符串轉(zhuǎn)換為數(shù)值(整型)

DataDF['Quantity'] = DataDF['Quantity'].astype('int')#字符串轉(zhuǎn)換為數(shù)值(浮點型)DataDF['UnitPrice'] = DataDF['UnitPrice'].astype('float')

日期調(diào)整前(為求簡便這里用已經(jīng)剔除分秒,剔除的辦法后面在格式一致化的空格分割再詳細說)

#數(shù)據(jù)類型轉(zhuǎn)換:字符串轉(zhuǎn)換為日期

#errors='coerce' 如果原始數(shù)據(jù)不符合日期的格式,轉(zhuǎn)換后的值為空值NaTDataDF.loc[:,'InvoiceDate']=pd.to_datetime(DataDF.loc[:,'InvoiceDate'],format='%d/%m/%Y',errors='coerce')#!!?? format 是你[原始數(shù)據(jù)]中日期的格式%y 兩位數(shù)的年份表示(00-99)%Y 四位數(shù)的年份表示(000-9999)%m 月份(01-12)%d 月內(nèi)中的一天(0-31)%H 24小時制小時數(shù)(0-23)%I 12小時制小時數(shù)(01-12)%M 分鐘數(shù)(00-59)%S 秒(00-59)

日期類型調(diào)整后

數(shù)據(jù)類型調(diào)整完畢

三、修改列名

修改前

#建立字典字典:舊列名和新列名對應(yīng)關(guān)系

colNameDict = {'InvolceDate':'SaleDate','StockCode':'StockNo'}#!! ??一定要舊列名放在冒號前#每組對應(yīng)關(guān)系以[逗號]隔開salesDf.rename(columns = colNameDict,inplace=True)

修改后

四、選擇部分子集

這是一個8列*541909行的數(shù)據(jù)集。

#選擇子集,選擇其中一列

subDataDF1=DataDF["InvoiceDate"]

#選擇子集,選擇其中兩列

subDataDF1=DataDF[["InvoiceDate","UnitPrice"]]

利用切片篩選 數(shù) 據(jù)功能 df.loc

https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.loc.html#pandas.DataFrame.loc

loc這個代碼有點像Excel里面的鼠標左鍵,可以隨意拉動你需要的數(shù)據(jù)進行切片。

以逗號作為隔開的界限,左邊為index,右邊為column

subDataDF1=DataDF.loc[:,"InvoiceDate"]

subDataDF1#單一個冒號意味著不作限制的全選

subDataDF2=DataDF.loc[0:9,:]

subDataDF2

subDataDF3=DataDF.loc[1:9,"StockCode":"CustomerID"]

subDataDF3

五、邏輯問題需要篩選

還是Dataframe.loc這個函數(shù)的知識點。

由于loc還可以判斷條件是否為True

DataDF.loc[:,'UnitPrice']>0

一般來說價格不能為負,所以從邏輯上來說如果價格是小于0的數(shù)據(jù)應(yīng)該予以篩出

#刪除異常值:通過條件判斷篩選出數(shù)據(jù)

#查詢條件querySer=DataDF.loc[:,'Quantity']>0#應(yīng)用查詢條件print('刪除異常值前:',DataDF.shape)DataDF=DataDF.loc[querySer,:]print('刪除異常值后:',DataDF.shape)

六、格式一致化

大小寫/去除空格

將我們數(shù)據(jù)中所有的Descrption改成大寫:

DataDF['Description']= DataDF['Description'].str.upper()

類似的代碼還有 字符串修改方法:

str().

upper()lower()title()lstrip()strip()DataDF['Description']= DataDF['Description'].str.strip()

2. 去除字符串符號 去亂碼

3. 空格分割

#定義函數(shù):分割I(lǐng)nvoiceDate,獲取InvoiceDate

#輸入:timeColSer InvoiceDate這一列,是個Series數(shù)據(jù)類型#輸出:分割后的時間,返回也是個Series數(shù)據(jù)類型def splitSaletime(timeColSer):timeList=[]for value in timeColSer:#例如2018/01/01 12:50,分割后為:2018-01-01dateStr=value.split(' ')[0]timeList.append(dateStr)#將列表轉(zhuǎn)行為一維數(shù)據(jù)Series類型timeSer=pd.Series(timeList)return timeSer

最后再賦值回去

DataDF.loc[:,'InvoiceDate']=splitSaletime(DataDF.loc[:,'InvoiceDate'])

七、處理缺失值

python缺失值有3種:

1)Python內(nèi)置的None值

2)在pandas中,將缺失值表示為NA,表示不可用not available。

3)對于數(shù)值數(shù)據(jù),pandas使用浮點值NaN(Not a Number)表示缺失數(shù)據(jù)。后面出來數(shù)據(jù),如果遇到錯誤:說什么float錯誤,那就是有缺失值,需要處理掉

所以,缺失值有3種:None,NA,NaN

那None和NaN有什么區(qū)別呢:

None是Python的一種數(shù)據(jù)類型,

NaN是浮點類型

兩個都用作空值

1、去除缺失值

# 再一次提醒檢查缺失數(shù)據(jù)

DataDF.isnull().sum().sort_values(ascending=False)

去除缺失值的知識點:

DataFrame.dropna

DataFrame.dropna(axis=0, how='any', thresh=None, subset=None, inplace=False)

# 默認(axis=0)是逢空值剔除整行,設(shè)置關(guān)鍵字參數(shù)axis=1表示逢空值去掉整列

# 'any'如果一行(或一列)里任何一個數(shù)據(jù)有任何出現(xiàn)Nan就去掉整行,‘a(chǎn)ll’一行(或列)每一個數(shù)據(jù)都是Nan才去掉這整行DataDF.dropna(how='any')DataDF.dropna(how='all')# 更精細的thresh參數(shù),它表示留下此行(或列)時,要求有多少[非缺失值]DataDF.dropna(thresh = 6 )

2、填充缺失內(nèi)容:某些缺失值可以進行填充,方法有以下四種:

1) 以業(yè)務(wù)知識或經(jīng)驗推測(默認值)填充缺失值

2) 以同一指標的計算結(jié)果(均值、中位數(shù)、眾數(shù)等)填充缺失值

3) 用相鄰值填充缺失值

4) 以不同指標的計算結(jié)果填充缺失值

去除缺失值的知識點:

DataFrame.fillna

https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.fillna.html#pandas.DataFrame.fillna

1) 用默認值填充- df.fillna(' ')

我們應(yīng)該去掉那些不友好的 NaN 值。但是,我們應(yīng)該用什么值替換呢?這個時候可能要結(jié)合你對這個數(shù)據(jù)集的理解,看填充什么數(shù)據(jù)才是比較合適,以下是一下常用的方法。

在這個數(shù)據(jù)集中,我們大致判斷CustomerID如果是不太重要的,就我們可以用使用""空字符串或其他默認值。

DataDF.Country= DataDF.Country.fillna('Not Given')

上面,我們就將“country”整個列使用“”空字符串替換了,或者,我們也可以輕易地使用“Not Given”這樣的默認值進行替換。

如果想了解更多 fillna() 的詳細信息參考 pandas.DataFrame.fillna

pandas.pydata.org

2) 以同一指標的計算結(jié)果(均值、中位數(shù)、眾數(shù)等)填充缺失值

平均值- df.fillna(df.mean())

使用數(shù)字類型的數(shù)據(jù)有可能可以通過這樣的方法來去減少錯誤。

比如,這個案例里面的價格。如果用0或者"Not Given"等來去填充都不太合適,但這個大概的價格是可以根據(jù)其他數(shù)據(jù)估算出來的。

DataDF.UnitPrice = DataDF.UnitPrice.fillna(DataDF.UnitPrice.mean())

3)除此,還有一種常見的方法,就是用相鄰的值進行填充,

這在時間序列分析中相當常見,用前面相鄰的值向后填充,也可以用后面相鄰的值向前填充。

print(DataDF)

print(DataDF.UnitPrice.fillna(method='ffill')) # 前向后填充print(DataDF.UnitPrice.fillna(method='bfill')) # 后向前填充

填充后

4) 以不同指標的計算結(jié)果填充缺失值

關(guān)于這種方法年齡字段缺失,但是有屏蔽后六位的身份證號可以推算具體的年齡是多少。

總結(jié)

以上是生活随笔為你收集整理的pandas用众数填充缺失值_7步搞定数据清洗-Python数据清洗指南的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。