Pandas 使用指南(上)

Pandas 使用指南(上) 基本數(shù)據(jù)結(jié)構(gòu)
http://blkstone.github.io/2015/11/21/pandas-tutorial-1/

一、Pandas介紹
終于寫到了作者最想介紹,同時也是Python在數(shù)據(jù)處理方面功能最為強(qiáng)大的擴(kuò)展模塊了。在處理實際的金融數(shù)據(jù)時,一個條數(shù)據(jù)通常包含了多種類型的數(shù)據(jù),例如,股票的代碼是字符串,收盤價是浮點型,而成交量是整型等。在C++中可以實現(xiàn)為一個給定結(jié)構(gòu)體作為單元的容器,如向量(vector,C++中的特定數(shù)據(jù)結(jié)構(gòu))。在Python中,pandas包含了高級的數(shù)據(jù)結(jié)構(gòu)Series和DataFrame,使得在Python中處理數(shù)據(jù)變得非常方便、快速和簡單。
pandas不同的版本之間存在一些不兼容性,為此,我們需要清楚使用的是哪一個版本的pandas。現(xiàn)在我們就查看一下量化實驗室的pandas版本:

import pandas as pd
pd.__version__
'0.14.1'

pandas主要的兩個數(shù)據(jù)結(jié)構(gòu)是Series和DataFrame,隨后兩節(jié)將介紹如何由其他類型的數(shù)據(jù)結(jié)構(gòu)得到這兩種數(shù)據(jù)結(jié)構(gòu),或者自行創(chuàng)建這兩種數(shù)據(jù)結(jié)構(gòu),我們先導(dǎo)入它們以及相關(guān)模塊:

import numpy as np
import numpy as np
import pandas as pd

二、Pandas數(shù)據(jù)結(jié)構(gòu):Series

從一般意義上來講,Series可以簡單地被認(rèn)為是** 帶索引的一維數(shù)組(或一維表) **。Series和一維數(shù)組最主要的區(qū)別在于Series類型具有索引(index),可以和另一個編程中常見的數(shù)據(jù)結(jié)構(gòu)哈希(Hash)聯(lián)系起來。

2.1 創(chuàng)建Series

創(chuàng)建一個Series的基本格式是s = Series(data, index=index, name=name),以下給出幾個創(chuàng)建Series的例子。首先我們從數(shù)組創(chuàng)建Series:

a = np.random.randn(5)
print "a is an array:"
print a
s = Series(a)
print "s is a Series:"
print s

可以在創(chuàng)建Series時添加index,并可使用Series.index查看具體的index。需要注意的一點是,當(dāng)從數(shù)組創(chuàng)建Series時,若指定index,那么index長度要和data的長度一致:


s = Series(np.random.randn(5), index=['a', 'b', 'c', 'd', 'e'])
print ss.index

創(chuàng)建Series的另一個可選項是name,可指定Series的名稱,可用Series.name訪問。在隨后的DataFrame中,每一列的列名在該列被單獨取出來時就成了Series的名稱:

s = Series(np.random.randn(5), index=['a', 'b', 'c', 'd', 'e'], name='my_series')
print s
print s.name

Series還可以從字典(dict)創(chuàng)建:

d = {'a': 0., 'b': 1, 'c': 2}
print "d is a dict:"
print d
s = Series(d)
print "s is a Series:"
print s

讓我們來看看使用字典創(chuàng)建Series時指定index的情形(index長度不必和字典相同):

Series(d, index=['b', 'c', 'd', 'a'])

我們可以觀察到兩點:一是字典創(chuàng)建的Series,數(shù)據(jù)將按index的順序重新排列;二是index長度可以和字典長度不一致,如果多了的話,pandas將自動為多余的index分配NaN(not a number,pandas中數(shù)據(jù)缺失的標(biāo)準(zhǔn)記號),當(dāng)然index少的話就截取部分的字典內(nèi)容。
如果數(shù)據(jù)就是一個單一的變量,如數(shù)字4,那么Series將重復(fù)這個變量:

Series(4., index=['a', 'b', 'c', 'd', 'e'])

2.2 Series數(shù)據(jù)的訪問

訪問Series數(shù)據(jù)可以和數(shù)組一樣使用下標(biāo),也可以像字典一樣使用索引,還可以使用一些條件過濾:

s = Series(np.random.randn(10),index=['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'])
s[0]

使用切片技巧

s[:2]
s[[2,0,4]]
s[['e', 'i']]
s[s > 0.5]
'e' in s => True

三、Pandas數(shù)據(jù)結(jié)構(gòu):DataFrame

在使用DataFrame之前,我們說明一下DataFrame的特性。DataFrame是將數(shù)個Series按列合并而成的二維數(shù)據(jù)結(jié)構(gòu),每一列單獨取出來是一個Series,這和SQL數(shù)據(jù)庫中取出的數(shù)據(jù)是很類似的。所以,按列對一個DataFrame進(jìn)行處理更為方便,用戶在編程時注意培養(yǎng)按列構(gòu)建數(shù)據(jù)的思維。DataFrame的優(yōu)勢在于可以方便地處理不同類型的列,因此,就不要考慮如何對一個全是浮點數(shù)的DataFrame求逆之類的問題了,處理這種問題還是把數(shù)據(jù)存成NumPy的matrix類型比較便利一些。

3.1 創(chuàng)建DataFrame

首先來看如何從字典創(chuàng)建DataFrame。DataFrame是一個二維的數(shù)據(jù)結(jié)構(gòu),是多個Series的集合體。我們先創(chuàng)建一個值是Series的字典,并轉(zhuǎn)換為DataFrame:

d = {'one': Series([1., 2., 3.], index=['a', 'b', 'c']), 'two': Series([1., 2., 3., 4.], index=['a', 'b', 'c', 'd'])}
df = DataFrame(d)
print df

可以指定所需的行和列,若字典中不含有對應(yīng)的元素,則置為NaN:

df = DataFrame(d, index=['r', 'd', 'a'], columns=['two', 'three'])
print df

可以使用dataframe.index和dataframe.columns來查看DataFrame的行和列,dataframe.values則以數(shù)組的形式返回DataFrame的元素:

print "DataFrame index:"
print df.index
print "DataFrame columns:"
print df.columns
print "DataFrame values:"
print df.values

DataFrame也可以從值是數(shù)組的字典創(chuàng)建,但是各個數(shù)組的長度需要相同:

d = {'one': [1., 2., 3., 4.], 'two': [4., 3., 2., 1.]}
df = DataFrame(d, index=['a', 'b', 'c', 'd'])print df

值非數(shù)組時,沒有這一限制,并且缺失值補成NaN:

d= [{'a': 1.6, 'b': 2}, {'a': 3, 'b': 6, 'c': 9}]
df = DataFrame(d)
print df

在實際處理數(shù)據(jù)時,有時需要創(chuàng)建一個空的DataFrame,可以這么做:

df = DataFrame()
print df

另一種創(chuàng)建DataFrame的方法十分有用,那就是使用concat函數(shù)基于Serie或者DataFrame創(chuàng)建一個DataFrame

a = Series(range(5))b = Series(np.linspace(4, 20, 5))df = pd.concat([a, b], axis=1)
print df

其中的axis=1表示按列進(jìn)行合并,axis=0表示按行合并,并且,Series都處理成一列,所以這里如果選axis=0的話,將得到一個10×1的DataFrame。下面這個例子展示了如何按行合并DataFrame成一個大的DataFrame:

df = DataFrame()
index = ['alpha', 'beta', 'gamma', 'delta', 'eta']
for i in range(5): 
  a = DataFrame([np.linspace(i, 5*i, 5)], index=[index[i]]) 
print a df = pd.concat([df, a], axis=0)
print df

3.2 DataFrame數(shù)據(jù)的訪問

首先,再次強(qiáng)調(diào)一下DataFrame是以列作為操作的基礎(chǔ)的,全部操作都想象成先從DataFrame里取一列,再從這個Series取元素即可。可以用datafrae.column_name選取列,也可以使用dataframe[]操作選取列,我們可以馬上發(fā)現(xiàn)前一種方法只能選取一列,而后一種方法可以選擇多列。若DataFrame沒有列名,[]可以使用非負(fù)整數(shù),也就是“下標(biāo)”選取列;若有列名,則必須使用列名選取,另外datafrae.column_name在沒有列名的時候是無效的:

print df[1]
print type(df[1])
df.columns = ['a', 'b', 'c', 'd', 'e']
print df['b']
print type(df['b'])
print df.b
print type(df.b)
print df[['a', 'd']]
print type(df[['a', 'd']])

以上代碼使用了dataframe.columns為DataFrame賦列名,并且我們看到單獨取一列出來,其數(shù)據(jù)結(jié)構(gòu)顯示的是Series,取兩列及兩列以上的結(jié)果仍然是DataFrame。訪問特定的元素可以如Series一樣使用下標(biāo)或者是索引:

print df['b'][2]
print df['b']['gamma']

若需要選取行,可以使用dataframe.iloc按下標(biāo)選取,或者使用dataframe.loc按索引選取:

print df.iloc[1]
print df.loc['beta']

選取行還可以使用切片的方式或者是布爾類型的向量:

print "Selecting by slices:"
print df[1:3]
bool_vec = [True, False, True, True, False]
print "Selecting by boolean vector:"
print df[bool_vec]

行列組合起來選取數(shù)據(jù):

print df[['b', 'd']].iloc[[1, 3]]
print df.iloc[[1, 3]][['b', 'd']]
print df[['b', 'd']].loc[['beta', 'delta']]
print df.loc[['beta', 'delta']][['b', 'd']]

如果不是需要訪問特定行列,而只是某個特殊位置的元素的話,dataframe.at和dataframe.iat是最快的方式,它們分別用于使用索引和下標(biāo)進(jìn)行訪問:

print df.iat[2, 3]
print df.at['gamma', 'd']

dataframe.ix可以混合使用索引和下標(biāo)進(jìn)行訪問,唯一需要注意的地方是行列內(nèi)部需要一致,不可以同時使用索引和標(biāo)簽訪問行或者列,不然的話,將會得到意外的結(jié)果:

print df.ix['gamma', 4]
print df.ix[['delta', 'gamma'], [1, 4]]
print df.ix[[1, 2], ['b', 'e']]
print "Unwanted result:"
print df.ix[['beta', 2], ['b', 'e']]
print df.ix[[1, 2], ['b', 4]]

參考資料
[1] 量化分析師的Python日記【第5天:數(shù)據(jù)處理的瑞士軍刀pandas】
[2] pandas文檔

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容