1. 程式人生 > >用pandas清洗資料具體步驟(基礎篇一)

用pandas清洗資料具體步驟(基礎篇一)

引言

     資料清洗是一項複雜且繁瑣(kubi)的工作,同時也是整個資料分析過程中最為重要的環節。但在實際的工作中一個分析專案70%左右的時間花在清洗資料上面。資料清洗的目的有兩個,第一是通過清洗讓資料可用。第二是讓資料變的更適合進行後續的分析工作。換句話說就是有”髒”資料要洗,乾淨的資料也要洗。本篇文章將用一個簡單的範例來介紹使用pandas進行資料清洗的流程。

讀取資料

      pandas模組中有專門針對xlsx和xls這類excel檔案的讀取方法read_excel。當然用的最多的還是read_csv檔案。因為excel檔案最多隻能儲存100多萬行,但是csv檔案可以儲存上億行資料。既然是簡單範例,我就只使用execl來讀取了。

tt=pd.read_excel(r'd:\\000030.xlsx',sheet_name='Sheet1')
#直接讀取硬碟中的excel檔案,變成Dataframe格式 
表格格式如下圖所示:


從表格中可以看出,第一存在很多空值;第二還有很多億元,萬元等字串影響了進行算術運算。第一步我們首先要處理空值:

處理空值

這裡涉及到對空值的處理:1刪除2替換3填充

刪除又分為是每行有一個空格就刪除該行還是有三個空值就刪除該行;

替換可以用上下行的值替換或者是用平均值替換

print (tt.isnull().any())   # 這是按照列統計的空值
print (tt[tt.isnull().values==True]) #檢視哪些值是空值

# 這裡涉及到對空值的處理:刪除還是替換然後還有填充(這裡刪除分為有一個空值刪除還是有兩個空值刪除一行。替換可以用特定值替換或者是用平均值替換)
tt.fillna(0,inplace=True)  # 根據本例的特點,空值可以填充0

對行索引和列索引進行處理

具體專案中有擷取一部分行索引和擷取一部分列索引的操作。

# 這裡我要替換列名'2017-03-31'為'2017/03/31'格式。有兩種方法一是Dataframe重建表格二是用rename替換行索引或者列索引
print(tt.shape)  # 看錶格有多少行多少列
a_list=list(tt.columns)
for_col=[ x.replace('-','/') for x in a_list]

# 按照情況只選擇前20列
tt.columns=for_col
tt=tt.ix[:,0:20]

# 替換行索引
b_list=list(tt.index)
for_index=['20181213{0:0>4}'.format(x) for x in b_list]   #使用列表推導和format函式改變索引
tt.index=for_index



檢視重複值

然後對錶格的資料進行校驗。看是否存在重複值:

tt.drop_duplicates(keep=False,inplace=True)
# 重複的是科目\時間  2017-09-30  2017-06-30  2017-03-31  2016-12-31 把重複的值全部刪除
print(tt[tt.duplicated(keep=False)])
# 檢驗。現在沒有重複值

尋找異常值

      異常值分為兩種:一種是非法資料,比如本來應該是數字列的中間夾雜著一些漢字或者是符號;第二種是異常資料,異乎尋常的大數值或者是小數值。

      我故意在兩個數字列的空值中插入兩個非法值,一個是“E”一個是“-”。然後通過程式找出異常值並修改成0

def turning(x):
    if type(x)==str:
        if x[-2:]=='億元' or x[-2:]=='億股':
            x=float(x[:-2])*100000000
        elif x[-2:]=='萬元':
            x=float(x[:-2])*10000
        elif x[-1:]=='元':
            x=float(x[:-1])
    return x
tt=tt.applymap(turning)

# 數字列中有無字元。可以看到表格從第一列開始才有數字。判斷某一列資料是否全部是int或者float。如不是打印出來
for i in range(1,len(tt.columns)):
    if ~tt.ix[:,i].apply(lambda x:isinstance(x,(int,float))).all():
        print(tt[~tt.ix[:,i].apply(lambda x:isinstance(x,(int,float)))])
        print(i)

# 找到兩個非法值。需要及時處理
tt.ix['201812130091':'201812130096',:]=tt.ix['201812130091':'201812130096',:].replace('E',0).replace('-',0)
print (tt.ix['201812130091':'201812130096',:])

去除空格

注意只有對字串類別的列才可以進行去除空格的操作。

tt.ix[:,0]=tt.ix[:,0].str.strip()

最後清洗的結果如下: