1. 程式人生 > >利用Python Pandas進行資料預處理-資料清洗

利用Python Pandas進行資料預處理-資料清洗

資料缺失、檢測和過濾異常值、移除重複資料

資料缺失
資料缺失在大部分資料分析應用中都很常見,Pandas使用浮點值NaN表示浮點和非浮點陣列中的缺失資料,他只是一個便於被檢測出來的資料而已。

from pandas import Series,DataFrame

string_data=Series(['abcd','efgh','ijkl','mnop'])

print(string_data)
print("...........\n")
print(string_data.isnull())

這裡寫圖片描述

Python內建的None值也會被當作NA處理

from pandas import
Series,DataFrame string_data=Series(['abcd','efgh','ijkl','mnop']) print(string_data) print("...........\n") string_data[0]=None print(string_data.isnull())

這裡寫圖片描述

處理NA的方法有四種:dropna,fillna,isnull,notnull

is(not)null,這一對方法對物件做出元素級的應用,然後返回一個布林型陣列,一般可用於布林型索引。

dropna,對於一個Series,dropna返回一個僅含非空資料和索引值的Series。

問題在於DataFrame的處理方式,因為一旦drop的話,至少要丟掉一行(列)。這裡解決方法與前面類似,還是通過一個額外的引數:dropna(axis=0,how=’any’,thresh=None),how引數可選的值為any或者all.all僅在切片元素全為NA時才拋棄該行(列)。thresh為整數型別,eg:thresh=3,那麼一行當中至少有三個NA值時才將其保留。

fillna,fillna(value=None,method=None,axis=0)中的value除了基本型別外,還可以使用字典,這樣可以實現對不同列填充不同的值。

過濾資料:
對於一個Series,dropna返回一個僅含非空資料和索引值的Series:

from pandas import Series,DataFrame
from numpy import nan as NA

data=Series([1,NA,3.5,NA,7])

print(data.dropna())

這裡寫圖片描述

另一個過濾DataFrame行的問題涉及問題序列資料。假設只想留一部分觀察資料,可以用thresh引數實現此目的:

from pandas import Series,DataFrame, np
from numpy import nan as NA

data=DataFrame(np.random.randn(7,3))

data.ix[:4,1]=NA
data.ix[:2,2]=NA

print(data)

print("...........")

print(data.dropna(thresh=2))

這裡寫圖片描述

不想濾除缺失的資料,而是通過其他方式填補“空洞”,fillna是最主要的函式。
通過一個常數呼叫fillna就會將缺失值替換為那個常數值:

from pandas import Series,DataFrame, np
from numpy import nan as NA

data=DataFrame(np.random.randn(7,3))

data.ix[:4,1]=NA
data.ix[:2,2]=NA

print(data)

print("...........")

print(data.fillna(0))

這裡寫圖片描述

若是通過一個字典呼叫fillna,就可以實現對不同列填充不同的值。

from pandas import Series,DataFrame, np
from numpy import nan as NA

data=DataFrame(np.random.randn(7,3))

data.ix[:4,1]=NA
data.ix[:2,2]=NA

print(data)

print("...........")

print(data.fillna({1:111,2:222}))

這裡寫圖片描述

可以利用fillna實現許多別的功能,比如可以傳入Series的平均值或中位數:

from pandas import Series,DataFrame, np
from numpy import nan as NA

data=Series([1.0,NA,3.5,NA,7])
print(data)
print("...........\n")
print(data.fillna(data.mean()))

這裡寫圖片描述

檢測和過濾異常值
異常值(outlier)的過濾或變換運算在很大程度上就是陣列運算。如下一個(1000,4)的標準正態分佈陣列:

from pandas import Series,DataFrame, np
from numpy import nan as NA

data=DataFrame(np.random.randn(1000,4))
print(data.describe())

print("\n....找出某一列中絕對值大小超過3的項...\n")
col=data[3]
print(col[np.abs(col) > 3] )

print("\n....找出全部絕對值超過3的值的行...\n")
print(col[(np.abs(data) > 3).any(1)] )

這裡寫圖片描述

移除重複資料
DataFrame的duplicated方法返回一個布林型Series,表示各行是否是重複行。

from pandas import Series,DataFrame, np
from numpy import nan as NA
import pandas as pd
import numpy as np

data=pd.DataFrame({'k1':['one']*3+['two']*4, 'k2':[1,1,2,2,3,3,4]})
print(data)
print("........\n")
print(data.duplicated())

這裡寫圖片描述

與此相關的還有一個drop_duplicated方法,它用於返回一個移除了重複行的DataFrame:

from pandas import Series,DataFrame, np
from numpy import nan as NA
import pandas as pd
import numpy as np

data=pd.DataFrame({'k1':['one']*3+['two']*4, 'k2':[1,1,2,2,3,3,4]})
print(data)
print("........\n")
print(data.drop_duplicates())

這裡寫圖片描述

上面的兩個方法會預設判斷全部列,也可以指定部分列進行重複項判斷,假設還有一列值,而只希望根據k1列過濾重複項。

from pandas import Series,DataFrame, np
from numpy import nan as NA
import pandas as pd
import numpy as np

data=pd.DataFrame({'k1':['one']*3+['two']*4, 'k2':[1,1,2,2,3,3,4]})
data['v1']=range(7)
print(data)
print("........\n")
print(data.drop_duplicates(['k1']))

這裡寫圖片描述

duplicates和drop_duplicates預設保留第一個出現的值組合。傳入take_last=True則保留最後一個:

from pandas import Series,DataFrame, np
from numpy import nan as NA
import pandas as pd
import numpy as np

data=pd.DataFrame({'k1':['one']*3+['two']*4, 'k2':[1,1,2,2,3,3,4]})
data['v1']=range(7)
print(data)
print("........\n")
print(data.drop_duplicates(['k1','k2'],take_last=True))

這裡寫圖片描述