1. 程式人生 > >第1章-資料探索(2)-資料預處理之Python實現

第1章-資料探索(2)-資料預處理之Python實現

簡介

Python中,在資料處理這方面最流行的包應當是屬於Pandas了。Pandas與Scipy一樣,都是基於NumPy這個包開發出來的,所以使用時,都需要引用Numpy。Pandas中的DataFrame與R語言中的資料框的設計理念基本是一致的。不光如此,除了是DataFrame資料型別以外,Pandas還提供時間序列型別Series,以及面板型別Panel。

import numpy as np
import pandas as pd
from pandas import Series, DataFrame, Panel

接下來,我們先來介紹一下Pandas的基本使用方法,然後再根據前一講用Pandas進行實現,資料型別主要介紹DataFrame。下面的實現,預設以及按上述程式碼匯入np以及pd、DataFrame等。

正文

一,Pandas介紹

1,I/O 資料的匯入與匯出

(1) 利用pandas的函式匯入資料
在這裡插入圖片描述
read_csv() / read_table() 的詳細引數
在這裡插入圖片描述
逐塊讀入資料示例

chunker = pd.reade_csv(path, chunksize = 100)
tot = Serise([])
for piece in chunker :
    tot = tot.add(piece[‘key’],value_counts(), fill_value= 0)
tot = tot.order(ascending=False)

(2) 利用pandas.DataFrame匯出資料
在這裡插入圖片描述

2, 資料的索引與篩選

(1) pandas 會為你自動從0生成索引值

DataFrame是一個表格型的資料結構,它含有一組有序的列,每列可以是不同的值型別(數值,字串,布林值等)。可以與Python中的字典型別互轉。

data = {'state':['fe','te','eea'],'year':[2018,2017,2016],'avgage':[87,85,89]}
frame = DataFrame(data)
print frame

資料中,預設的0,1,2即為自動生成的索引值。
|avgage | state | year
0 | 87 | fe | 2018
1 | 85 | te | 2017
2 | 89 | eea | 2016

(2) 根據索引選取資料

  • 通過冒號選取行
    例: frame[:2]

  • 通過布林陣列選取行
    例:frame[frame['year']==2018]

  • 通過列索引選取列
    例:frame[ 'year', 'state'] ]

  • 通過ix選取,(或 iloc操作相同)
    選取某行:obj.ix[val]
    選取某列:obj.ix[ : , val]
    同時選中某行和某列:obj.ix[ val1, val2 ]

3,資料的函式應用

Numpy的通用函式ufunc是可用於pandas,此外,另外我們還可以使用下面幾種常用的方式,詳細點選此處檢視詳情。

  • DataFrame.apply()
  • DataFrame.applymap()
  • DataFrame.aggregate()
  • DataFrame.transform()

例:
自定義一極差函式:f = lambda x: x.max() -x.min()
計算每列的極差值: frame.apply(f, axis = 1)

下面列出一些常用的自帶函式

在這裡插入圖片描述

在這裡插入圖片描述

在這裡插入圖片描述

在這裡插入圖片描述

4,資料缺失的處理

在這裡插入圖片描述

我們把之前的例子改一下,通過np.nan來賦值缺失值。

data = {'state':['fe',np.nan,'eea'],'year':[2018,2017,2016],'avgage':[87,85,np.nan]}
frame = DataFrame(data,columns=['year','state','avgage'])
print frame

(1) 檢視哪些元素有缺失值isnull()
frame.isnull()
返回值如下
year state avgage
0 False False False
1 False True False
2 False False True

(2)count統計,忽略NaN
frame.count()統計時,會跳過NaN
類似的,還有sum()等

(3)fillna填充缺失值

  • 所有缺失值,填充為統一值(數值或字元均可)
    例,所有缺失值填充為0: frame.fillna(0)

  • 限制填充缺失值
    例,選取state列,僅填充第一個缺失值: frame['state'].fillna(0, limit=1)

5,合併資料集

pandas自帶的資料大體有三個方法

  • pd.merge
  • pd.join,類似merge簡化版
  • pd.concat,軸向連線,類似於numpy.concatenate(),預設情況下,concat中的axis=0,表示新增行

pd.merge引數如下
在這裡插入圖片描述

pd.merge(df1, df2, how='innner', on = 'key')

表示:用df1中的key列 與df2中的key列進行內關聯,合併取得資料。

pd.merge( df1, df2 , left_on = 'key', right_index = True, how = 'outer')

表示:用df1中的key列 與df2中索引列進行外關聯,合併取得資料。

6,資料的聚合與分組運算

DataFrame.groupby()

  • 1,根據列分組:dataframe.groupby([列1,列2]).mean()
    ⚠️分組中的缺失值預設會被排除在外計算
  • 2,根據字典或Series分組:dataframe.groupby(字典或Series).mean()
  • 3,根據函式分組:dataframe.groupby(len).mean() ,比如根據長度len來分組
  • 4,根據索引分組:dataframe.groupby(level=‘city’,axis=1).count()

groupby將會產生一個GroupBy物件,該物件可以進行迭代、運用聚合函式等

可以用groupby物件.agg(func), 通過agg使用自己寫的的聚合函式func
agg(),可選取多個函式,agg(‘mean’, ‘count’, ’sum’, ’median’, ’std’, ’var’, ’min’, ’max’, ’prod’, ’first’, ’last’ )

二,利用Pandas進行資料預處理

前一節講過,預處理的四個步驟,接下來演示相應的操作:

資料清洗:SINCE原則處理資料
資料整合:pandas.merge方法
資料變換:pandas、scipy、numpy的處理
資料規約:會放到第五章進行講解

1,資料清洗

  • Simple原則: 發現重複與冗餘
data = {'state':['a','b','c','a','b','c'],'year':[2018,2016,2017,2018,2016,2017],'avgage':[87,85,88,87,85,88]}
frame = DataFrame(data,columns=['year','state','avgage'])
print frame

frame[frame.duplicated()].count()   #統計所有資料全部重複的有多少

frame[frame.duplicated()]  #統計重複的資料是哪幾個
 	year 	state 	avgage
3 	2018 	a 	87
4 	2016 	b 	85
5 	2017 	c 	88

frame.drop_duplicates()  #把重複的刪除,但是不會刪除原始資料

對於冗餘,與資料規約的步驟是基本一致的,會合併到資料規約的步驟來計算。

  • Integral原則:處理缺失處理

處理缺失值的具體理論方法,參見第六章,此處僅介紹一下,如何發現以及填充缺失值。

data = {'state':['a','b','c',np.nan,'b','c'],'year':[2018,2016,np.nan,2018,2016,2017],'avgage':[87,85,88,np.nan,85,88]}
frame = DataFrame(data,columns=['year','state','avgage'])
print frame

frame.count()         # 統計了每列剔除缺失值以後的個數
frame.isnull().sum()  # 統計了每列缺失值的個數

frame.fillna(0)   #把缺失值都填充為0,此處也可以是字串,不過很少有把缺失值填充統一值的

對於不同的列,動態指定不同列的填充值

frame.fillna(frame.mean())  # 將每一列的均值填充到各列自己的缺失值中,同理最大最小值等統計值均可。

# 可以看到,只有數值型的列,適合用均值這種統計指標,對於列state, 我們可以用頻數高的眾數
# 當然眾數可能不是唯一的,所以我們取第一個眾數,來填充state列
frame['state'].fillna(frame.mode()['state'][0])

# 運用自定義函式來填充, 假設自定義函式就是取眾數的第一個值
f = lambda x: x.fillna(x.mode()[0])
frame.apply(f)
  • Normal原則:統一格式並標準化
    統一格式,基本就是修改並賦值的過程,此處不再討論。

對於數值型變數,我們有兩種方式,標準化:

歸一化公式
X n e w = x x m i n x m a x x m i n X_{new} = \frac{x-x_{min}}{x_{max}-x_{min}}

f = lambda x: ( x - min(x) )/ ( max(x) - min(x) )
frame['avgage'].transform(f)

標準化公式
X n e w = x u σ X_{new} = \frac{x-u}{σ}

f = lambda x: ( x - x.mean() )/ x.std()
frame['avgage'].transform(f)
  • Consistent一致性原則:就要以業務與經驗為主來判斷
  • Effective有效原則:錯誤與異常
    對於異常值,我們最簡單的方法是檢視樣本資料的分佈來得到結果。根據箱線圖的三個重要的分位數,在Q3+1.5IQR和Q1-1.5IQR的範圍以外的,認為是異常值,或者叫做離群點。
q1, q2, q3 = frame['avgage'].quantile([0.25,0.5,0.75])
IQR = q3-q1
O1 = q1 - 1.5*IQR
O2 = q3 + 1.5*IQR
(frame['avgage'] < O1) | (frame['avgage'] > O2 )   # 是否異常點的判斷

此外,還有專門研究異常檢測的方法論,可以參照第十八章異常檢測,來進行學習。

2,資料整合:

pandas.merge方法

dat1 = DataFrame({'key':['a','b','d'],
       'value1':[12,3,5],
      'year':[1998,1999,2001]})
dat2 = DataFrame({'key':['a','c','e'],
       'value2':[43,32,10],
      'mon':[12,10,10]})
      
# 通過key值內關聯起來
pd.merge(dat1,dat2,on = 'key',how='inner')

   key 	value1 	year 	mon 	value2
0 	a 	12 	    1998    12 	    43

# 通過key值左關聯起來
pd.merge(dat1,dat2,on = 'key',how='left')   # 或
pd.merge(dat1,dat2,left_on = 'key',right_on = 'key',how='left')

  key 	value1 	year 	 mon 	value2
0 	a 	12 	    1998 	 12.0 	 43.0
1 	b 	3 	    1999 	 NaN 	 NaN
2 	d 	5 	    2001 	 NaN 	 NaN

3,資料變換:

將數值屬性拆分成分類屬性

dat = DataFrame({'value':[12,3,5,3,5,6,7,8,2,5,8,1,4,8]})

#將資料分為三組,並且命名組1、2、3;
result = pd.cut(dat['value'],3,labels=['組1','組2','組3'])

#將分組變數dummy化
dum = pd.get_dummies(result)

#合併這些結果
pd.concat([dat,result,dum],axis=1)

上一節:第1章-資料探索(1)-資料預處理

下一節:第1章-資料探索(3)-資料預處理之R實現