1. 程式人生 > >機器學習之Pandas庫

機器學習之Pandas庫

1.1 pandas庫總體說明

Pandas基於NumPy、SciPy補充的大量資料操作功能,能實現統計、分組、排序、透視表,可以代替Excel的絕大部分功能

Pandas主要有2種重要資料結構:Series、DataFrame(一維序列,二維表)。資料型別的轉換需要用到pd.Series/DataFrame.

(1)Series

可以是一個樣本的所有觀測值或一個樣本的某一屬性的觀測值

如利用NumPy生成一個正態分佈的偽隨機數,共含4個值

Series1 = pd.Series(np.random.randn(4))

結果就自動添加了行索引index

0    -1.344609

1    0.177173

2    0.554958

3    -0.576237

過濾Series的方法是:print Series1<0 或 print Series1[Series1 < 0]。前者給出Boolean型別的輸出,後者給出具體的數值,僅僅輸出Series中小於0的數值。

可以使用Key-Value的方式儲存資料:

Series2 = pd.Series(Series1.values,index=['row_'+unicode(i) for i in range(4)])

同樣,Python的基礎資料結構字典也可以轉化為Series。

Series3 = pd.Series({"China":"Beijing","England":"GB","Japan":"Tokyo"})

輸出結果依舊是一個序列,但是因為字典是無序的,所有有可能的操作會打擾原字典的順序。如果需要順序不變,可以使用下面的方法明確指定這種秩序。

Series4_indexList = ["China",Japan","England"]

Series4 = pd.Series(Series3,index=Series4_indexList)

某些時候,index列表沒有相應的對應值,這樣會預設填補為空值,可以使用isnull(0,notnull())來返回boolean結果。

Series5_indexList = ["A",B","C","C"]

Series5 = pd.Series(Series1.values,index=Series5_indexList)

index允許重複,但是這樣很容易導致錯誤。

(2)DataFrame

DataFrame可以視作Series的有序集合,可以從資料庫、NumPy二維陣列、JSON中定義資料框。

NumPy二維陣列:

DF1 = pd.DataFrame(np.array([("Japan","Tokyo",4000),("S.Korea","Seoul",1000),("China","Beijing",9000)]),columns=["nation","capital","GDP"])

JSON:

DF2 = pd.DataFrame({"nation":["Japan","S.Korea","China"],"capital":["Tokyo","Seoul","Beijing"],"GDP":[4000,1000,9000]})

但是字典的key是無序的,所以我們又要用到剛才Series中的類似方法加以解決:

DF3 = pd.DataFrame(DF2,columns=["nation","capital","GDP"])

對應地,還可以認為指定行標秩序。

DF4 = pd.DataFrame(DF2,columns=["nation","capital","GDP"],index=[2,0,1])

在DataFrame中切片:

取列:推薦使用DF4["GDP"],最好別用DF4.GDP,容易與一些關鍵字(保留字)衝突

取行:DF4[0:1]或者DF4.ix[0]

區別在於前者取了第一行,後者取了index為0的第一行。

此外,如果要在資料框動態增加列,不能用"."的方式,而要用[]

DF4["region"]="East Asian"

 

1.2 代表性函式使用介紹

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

#建立物件
#1.通過傳遞一個list物件來建立一個Series
s = pd.Series([1,3,5,np.nan,6,8])
s

#2.通過傳遞一個numpy array,時間索引以及列標籤來建立一個DataFrame
dates = pd.date_range('20130101',periods=6)
dates

df=pd.DataFrame(np.random.randn(6,4),index=dates,columns=list('ABCD'))
df

#3.通過傳遞一個能夠被轉換成類似序列結構的字典物件來建立一個DataFrame
df2 = pd.DataFrame({'A':1,'B':pd.Timestamp('20130102'),'C':pd.Series(1,index=list(range(4)),dtype='float32'),'D':np.array([3]*4,dtype='int32'),'E':pd.Categorical(['tost','train','test','train']),'F':'foo'})
df2

#4.檢視不同列的資料型別
df2.dtypes


#檢視資料
#1.檢視frame中頭部和尾部的行
df.head()
df.tail(3)

#2.顯示索引、列和底層的numpy資料
df.index
df.columns
df.values

#3.describe()函式對於資料的快速統計彙總
df.describe()

#4.對資料的轉置
df.T

#5.按軸進行排序
df.sort_index(axis=1,ascending=False)

#6.按值進行排序
df.sort_values(by='B')


#選擇
#獲取
#1.選擇一個單獨的列,返回一個Series,等同於df.A
df['A']

#2.通過[]進行選擇,這將會對行進行切片
df[0:3]
df['20130102':'20130104']

#通過標籤選擇
#1.使用標籤來獲取一個交叉的區域
df.loc[dates[0]]

#2.通過標籤來在多個軸上進行選擇
df.loc[:,['A','B']]

#3.標籤切片
df.loc['20130102':'20130104',['A','B']]

#4.對於返回的物件進行維度縮減
df.loc['20130102',['A','B']]

#5.獲取一個標量
df.loc[dates[0],'A']

#6.快速訪問一個標量(與5等價)
df.at[dates[0],'A']

#通過位置選擇
#1.通過傳遞數值進行位置選擇
df.iloc[3]

#2.通過數值進行切片
df.iloc[3:5,0:2]

#3.通過指定一個位置的列表
df.iloc[[1,2,4],[0,2]]

#4.對行進行切片
df.iloc[1:3,:]

#5.對列進行切片
df.iloc[:,1:3]

#6.獲取特定值
df.iloc[1,1]
df.iat[1,1]

#布林索引
#1.使用一個單獨列的值來選擇資料
df[df.A >0]

#2.選擇資料
df[df>0]

#3.使用isin()方法來過濾
df2 = df.copy()
df2['E'] = ['one','one','two','three','four','three']
df2
df2[df2['E'].isin(['two','four'])]


#設定
#1.設定一個新列
s1 = pd.Series([1,2,3,4,5,6],index=pd.date_range('20130102',periods=6))
s1
df['F'] = s1

#2.通過標籤設定新的值
df.at[dates[0],'A'] = 0

#3.通過位置設定新的值
df.iat[0,1] = 0

#4.通過numpy陣列設定一組新值
df.loc[:,'D'] = np.array([5]*len(df))
df

#5.通過where操作設定新的值
df2 = df.copy()
df2[df2 >0] = -df2
df2

#缺失值處理
#1.reindex()方法
df1 = df.reindex(index=dates[0:4],columns=list(df.columns)+['E'])
df1.loc[dates[0]:dates[1],'E'] = 1
df1

#2.去掉包含缺失值的行
df1.dropna(how='any')

#3.對缺失值進行填充
df1.fillna(value=5)

#4.對資料進行布林填充
pd.isnull(df1)

#操作
#統計
#1.執行描述性統計
df.mean()

#2.在其他軸上進行相同操作
df.mean(1)

#3.對擁有不同維度,需要對齊的物件進行操作
s = pd.Series([1,3,5,np.nan,6,8],index=dates).shift(2)
s
df.sub(s,axis='index')


#Apply
#1.對資料應用函式
df.apply(np.cumsum)
df.apply(lambda X:x.max()-x.min())
#直方圖
s = pd.Series(np.random.randint(0,7,size=10))
s
s.value_counts()

#字串方法
s = pd.Series(['A','B','C','Aaba','Baca',np.nan,'CABA','dog','cat'])
s.str.lower()

#合併
df = pd.DataFrame(np.random.randn(10,4))
df
pieces = [df[:3],df[3:7],df[7:]]
pd.concat(pieces)

#join
left = pd.DataFrame({'key':['foo','foo'],'lval':[1,2]})
right = pd.DataFrame({'key':['foo','foo'],'rval':[4,5]})
left
right
pd.merge(left,right,on='key')

#append
df = pd.DataFrame(np.random.randn(8,4),columns=['A','B','C','D'])
df
s = df.iloc[3]
df.append(s,ignore_index=True)


#分組
df = pd.DataFrame({'A':['foo','bar','foo','bar','foo','bar','foo','foo'],'B':['one','one','two','three','two','two','one','three'],'C':np.random.randn(8),'D':np.random.randn(8)})
df

#1.分組並對每個分組執行sum函式
df.groupby('A').sum()

#2.通過多個列進行分組形成一個層次索引,然後執行函式
df.groupby(['A','B']).sum()


#Reshaping
tuples = list(zip(*[['bar','bar','baz','baz','foo','foo','qux','qux'],['one','two','one','two','one','two','one','two']]))
index = pd.MultiIndex.from_tuples(tuples,names=['first','second'])
df = pd.DataFrame(np.random.randn(8,2),index=index,columns=['A','B'])
df2 = df[:4]
df2
stacked = df2.stack()
stacked
stacked.unstack()
stacked.unstack(1)
stacked.unstack(0)

#資料透視表
df = pd.DataFrame({'A':['one','one','two','three']*3,'B':['A','B','C']*4,'C':['foo','foo','foo','bar','bar','bar']*2,'D':np.random.randn(12),'E':np.random.randn(12)})
df
pd.pivot_table(df,values='D',index=['A','B'],columns=['C'])

#匯入和儲存資料
#1.寫入csv檔案
df.to_csv('foo.csv')
#2.從csv檔案中讀取
pd.read_csv('foo.csv')

#1.寫入HDF5儲存
df.to_hdf('foo.h5','df')
#2.從HDF5儲存中讀取
pd.read_hdf('foo.h5','df')

#1.寫入excel檔案
df.to_excel('foo.xlsx',sheet_name='Sheet1')
#2.從excel檔案中讀取
pd.read_excel('foo.xlsx','Sheet1',index_col=None,na_values=['NA'])