Pandas最详细教程来了!
導讀:在Python中,進行數據分析的一個主要工具就是Pandas。Pandas是Wes McKinney在大型對沖基金AQR公司工作時開發的,后來該工具開源了,主要由社區進行維護和更新。
Pandas具有NumPy的ndarray所不具有的很多功能,比如集成時間序列、按軸對齊數據、處理缺失數據等常用功能。Pandas最初是針對金融分析而開發的,所以很適合用于量化投資。
作者:趙志強 劉志偉
來源:大數據DT(ID:hzdashuju)
在使用Pandas之前,需要導入Pandas包。慣例是將pandas簡寫為pd,命令如下:
import?pandas?as?pdPandas包含兩個主要的數據結構:Series和DataFrame。其中最常用的是DataFrame,下面我們先來學習一下DataFrame。
01 DataFrame入門
DataFrame是一個表格型的數據結構。每列都可以是不同的數據類型(數值、字符串、布爾值等)。
DataFrame既有行索引也有列索引,這兩種索引在DataFrame的實現上,本質上是一樣的。但在使用的時候,往往是將列索引作為區分不同數據的標簽。DataFrame的數據結構與SQL數據表或者Excel工作表的結構非常類似,可以很方便地互相轉換。
下面先來創建一個DataFrame,一種常用的方式是使用字典,這個字典是由等長的list或者ndarray組成的,示例代碼如下:
data={'A':['x','y','z'],'B':[1000,2000,3000],'C':[10,20,30]} df=pd.DataFrame(data,index=['a','b','c']) df運行結果如圖3-2所示。
▲圖3-2
我們可以看到,DataFrame主要由如下三個部分組成。
數據,位于表格正中間的9個數據就是DataFrame的數據部分。
索引,最左邊的a、b、c是索引,代表每一行數據的標識。這里的索引是顯式指定的。如果沒有指定,會自動生成從0開始的數字索引。
列標簽,表頭的A、B、C就是標簽部分,代表了每一列的名稱。
下文列出了DataFrame函數常用的參數。其中,“類似列表”代表類似列表的形式,比如列表、元組、ndarray等。一般來說,data、index、columns這三個參數的使用頻率是最高的。
data:ndarray/字典/類似列表 | DataFrame數據;數據類型可以是ndarray、嵌套列表、字典等
index:索引/類似列表 | 使用的索引;默認值為range(n)
columns:索引/類似列表 | 使用的列標簽;默認值為range(n)
dtype:dtype | 使用(強制)的數據類型;否則通過推導得出;默認值為None
copy:布爾值 | 從輸入復制數據;默認值為False
其中data的數據類型有很多種。
下文列舉了可以作為data傳給DataFrame函數的數據類型。
可以傳給DataFrame構造器的數據:
二維ndarray:可以自行指定索引和列標簽
嵌套列表或者元組:類似于二維ndarray
數據、列表或元組組成的字典:每個序列變成一列。所有序列長度必須相同
由Series組成的字典:每個Series會成為一列。如果沒有指定索引,各Series的索引會被合并
另一個DataFrame:該DataFrame的索引將會被沿用
前面生成了一個DataFrame,變量名為df。下面我們來查看一下df的各個屬性值。
獲取df數據的示例代碼如下:
df.values輸出結果如下:
array([['x',?1000,?10],['y',?2000,?20],['z',?3000,?30]],?dtype=object)獲取df行索引的示例代碼如下:
df.index輸出結果如下:
Index(['a',?'b',?'c'],?dtype='object')獲取df列索引(列標簽)的示例代碼如下:
df.columns輸出結果如下:
Index(['A',?'B',?'C'],?dtype='object')可以看到,行索引和列標簽都是Index數據類型。
創建的時候,如果指定了列標簽,那么DataFrame的列也會按照指定的順序進行排列,示例代碼如下:
df=pd.DataFrame(data,columns=['C','B','A'],index=['a','b','c']) df運行結果如圖3-3所示。
▲圖3-3
如果某列不存在,為其賦值,會創建一個新列。我們可以用這種方法來添加一個新的列:
df['D']=10 df運行結果如圖3-4所示。
▲圖3-4
使用del命令可以刪除列,示例代碼如下:
del?df['D'] df運行結果如圖3-5所示。
▲圖3-5
添加行的一種方法是先創建一個DataFrame,然后再使用append方法,代碼如下:
new_df=pd.DataFrame({'A':'new','B':4000,'C':40},index=['d']) df=df.append(new_df) df運行結果如圖3-6所示。
▲圖3-6
或者也可以使用loc方法來添加行,示例代碼如下:
df.loc['e']=['new2',5000,50] df運行結果如圖3-7所示。
▲圖3-7
loc方法將在后面的內容中詳細介紹。
索引的存在,使得Pandas在處理缺漏信息的時候非常靈活。下面的示例代碼會新建一個DataFrame數據df2。
df2=pd.DataFrame([1,2,3,4,5],index=['a','b','c','d','z'],columns=['E']) df2運行結果如圖3-8所示。
▲圖3-8
如果現在想要合并df和df2,使得df有一個新的列E,那么可以使用join方法,代碼如下:
df.join(df2)運行結果如圖3-9所示。
▲圖3-9
可以看到,df只接受索引已經存在的值。由于df2中沒有索引e,所以是NaN值,而且df2索引為z的值已經丟失了。為了保留df2中索引為z的值,我們可以提供一個參數,告訴Pandas如何連接。示例代碼如下:
df.join(df2,how='outer')運行結果如圖3-10所示。
▲圖3-10
在上述代碼中,how='outer'表示使用兩個索引中所有值的并集。連接操作的其他選項還有inner(索引的交集)、left(默認值,調用方法的對象的索引值)、right(被連接對象的索引值)等。
在金融數據分析中,我們要分析的往往是時間序列數據。下面介紹一下如何基于時間序列生成DataFrame。為了創建時間序列數據,我們需要一個時間索引。這里先生成一個DatetimeIndex對象的日期序列,代碼如下:
dates=pd.date_range('20160101',periods=8) dates輸出結果如下:
DatetimeIndex(['2016-01-01',?'2016-01-02',?'2016-01-03',?'2016-01-04','2016-01-05',?'2016-01-06',?'2016-01-07',?'2016-01-08'],dtype='datetime64[ns]',?freq='D')可以看到,使用Pandas的date_range函數生成的是一個DatetimeIndex對象。date_range函數的參數及說明如下所示:
start:字符串/日期時間 | 開始日期;默認為None
end:字符串/日期時間 | 結束日期;默認為None
periods:整數/None | 如果start或者end空缺,就必須指定;從start開始,生成periods日期數據;默認為None
freq:dtype | 周期;默認是D,即周期為一天。也可以寫成類似5H的形式,即5小時。其他的頻率參數見下文
tz:字符串/None | 本地化索引的時區名稱
normalize:布爾值 | 將start和end規范化為午夜;默認為False
name:字符串 | 生成的索引名稱
date_range函數頻率的參數及說明如下所示:
B:交易日
C:自定義交易日(試驗中)
D:日歷日
W:每周
M:每月底
SM:半個月頻率(15號和月底)
BM:每個月份最后一個交易日
CBM:自定義每個交易月
MS:日歷月初
SMS:月初開始的半月頻率(1號,15號)
BMS:交易月初
CBMS:自定義交易月初
Q:季度末
BQ:交易季度末
QS:季度初
BQS:交易季度初
A:年末
BA:交易年度末
AS:年初
BAS:交易年度初
BH:交易小時
H:小時
T,min:分鐘
S:秒
L,ms:毫秒
U,us:微秒
N:納秒
接下來,我們再基于dates來創建DataFrame,代碼如下:
df=pd.DataFrame(np.random.randn(8,4),index=dates,columns=list('ABCD')) df運行結果如圖3-11所示。
▲圖3-11
有了df,我們就可以使用多個基于DataFrame的內建方法了,下面來看看相關的示例。
按列求總和,代碼如下:
df.sum()輸出結果如下:
A????0.241727 B???-0.785350 C???-0.547433 D???-1.449231 dtype:?float64按列求均值,代碼如下:
df.mean()輸出結果如下:
A????0.030216 B???-0.098169 C???-0.068429 D???-0.181154 dtype:?float64按列求累計總和,代碼如下:
df.cumsum()運行結果如圖3-12所示。
▲圖3-12
使用describe一鍵生成多種統計數據,代碼如下:
df.describe()運行結果如圖3-13所示。
▲圖3-13
可以根據某一列的值進行排序,代碼如下:
df.sort_values('A')運行結果如圖3-14所示。
▲圖3-14
根據索引(日期)排序(這里是倒序),代碼如下:
df.sort_index(ascending=False)運行結果如圖3-15所示。
▲圖3-15
選取某一列,返回的是Series對象,可以使用df.A,代碼如下:
df['A']輸出結果如下:
2016-01-01???-1.142350 2016-01-02???-0.816178 2016-01-03????0.030206 2016-01-04????1.930175 2016-01-05????0.571512 2016-01-06????0.220445 2016-01-07????0.292176 2016-01-08???-0.844260 Freq:?D,?Name:?A,?dtype:?float64使用[]選取某幾行,代碼如下:
df[0:5]運行結果如圖3-16所示。
▲圖3-16
根據標簽(Label)選取數據,使用的是loc方法,代碼如下:
df.loc[dates[0]]輸出結果如下:
A???-1.142350 B???-1.999351 C????0.772343 D???-0.851840 Name:?2016-01-01?00:00:00,?dtype:?float64再來看兩個示例代碼。
df.loc[:,['A','C']]運行結果如圖3-17所示。
▲圖3-17
df.loc['20160102':'20160106',['A','C']]運行結果如圖3-18所示。
▲圖3-18
需要注意的是,如果只有一個時間點,那么返回的值是Series對象,代碼如下:
df.loc['20160102',['A','C']]輸出結果如下:
A???-0.816178 C???-0.595195 Name:?2016-01-02?00:00:00,?dtype:?float64如果想要獲取DataFrame對象,需要使用如下命令:
df.loc['20160102':'20160102',['A','C']]運行結果如圖3-19所示。
▲圖3-19
上面介紹的是loc方法,是按標簽(索引)來選取數據的。有時候,我們會希望按照DataFrame的絕對位置來獲取數據,比如,如果想要獲取第3行第2列的數據,但不想按標簽(索引)獲取,那么這時候就可以使用iloc方法。
根據位置選取數據,代碼如下:
df.iloc[2]輸出結果如下:
A????0.030206 B????0.759953 C???-1.446549 D???-0.874364 Name:?2016-01-03?00:00:00,?dtype:?float64再來看一個示例:
df.iloc[3:6,1:3]運行結果如圖3-20所示。
▲圖3-20
注意:對于DataFrame數據類型,可以使用[]運算符來進行選取,這也是最符合習慣的。但是,對于工業代碼,推薦使用loc、iloc等方法。因為這些方法是經過優化的,擁有更好的性能。
有時,我們需要選取滿足一定條件的數據。這個時候可以使用條件表達式來選取數據。這時傳給df的既不是標簽,也不是絕對位置,而是布爾數組(Boolean Array)。下面來看一下示例。
例如,尋找A列中值大于0的行。首先,生成一個布爾數組,代碼如下:
df.A>0輸出結果如下:
2016-01-01????False 2016-01-02????False 2016-01-03?????True 2016-01-04?????True 2016-01-05?????True 2016-01-06?????True 2016-01-07?????True 2016-01-08????False Freq:?D,?Name:?A,?dtype:?bool可以看到,這里生成了一個Series類型的布爾數組。可以通過這個數組來選取對應的行,代碼如下:
df[df.A>0]運行結果如圖3-21所示。
▲圖3-21
從結果可以看到,A列中值大于0的所有行都被選擇出來了,同時也包括了BCD列。
現在我們要尋找df中所有大于0的數據,先生成一個全數組的布爾值,代碼如下:
df>0運行結果如圖3-22所示。
▲圖3-22
下面來看一下使用df>0選取出來的數據效果。由圖3-23可以看到,大于0的數據都能顯示,其他數據顯示為NaN值。
df[df>0]運行結果如圖3-23所示。
▲圖3-23
再來看一下如何改變df的值。首先我們為df添加新的一列E,代碼如下:
df['E']=0 df運行結果如圖3-24所示。
▲圖3-24
使用loc改變一列值,代碼如下:
df.loc[:,'E']=1 df運行結果如圖3-25所示。
▲圖3-25
使用loc改變單個值,代碼如下:
df.loc['2016-01-01','E']?=?2 df運行結果如圖3-26所示。
▲圖3-26
使用loc改變一列值,代碼如下:
df.loc[:,'D']?=?np.array([2]?*?len(df)) df運行結果如圖3-27所示。
▲圖3-27
可以看到,使用loc的時候,x索引和y索引都必須是標簽值。對于這個例子,使用日期索引明顯不方便,需要輸入較長的字符串,所以使用絕對位置會更好。這里可以使用混合方法,DataFrame可以使用ix來進行混合索引。比如,行索引使用絕對位置,列索引使用標簽,代碼如下:
df.ix[1,'E']?=?3 df運行結果如圖3-28所示。
▲圖3-28
ix的處理方式是,對于整數,先假設為標簽索引,并進行尋找;如果找不到,就作為絕對位置索引進行尋找。所以運行效率上會稍差一些,但好處是這樣操作比較方便。
對于ix的用法,需要注意如下兩點。
假如索引本身就是整數類型,那么ix只會使用標簽索引,而不會使用位置索引,即使沒能在索引中找到相應的值(這個時候會報錯)。
如果索引既有整數類型,也有其他類型(比如字符串),那么ix對于整數會直接使用位置索引,但對于其他類型(比如字符串)則會使用標簽索引。
總的來說,除非想用混合索引,否則建議只使用loc或者iloc來進行索引,這樣可以避免很多問題。
02 Series
Series類似于一維數組,由一組數據以及相關的數據標簽(索引)組成。示例代碼如下:
import?pandas?as?pd s=pd.Series([1,4,6,2,3]) sOut:?
0????1 1????4 2????6 3????2 4????3在這段代碼中,我們首先導入pandas并命名為pd,然后向Series函數傳入一個列表,生成一個Series對象。在輸出Series對象的時候,左邊一列是索引,右邊一列是值。由于沒有指定索引,因此會自動創建0到(N-1)的整數索引。也可以通過Series的values和index屬性獲取其值和索引。示例代碼如下:
s.valuesOut:
array([1,?4,?6,?2,?3],?dtype=int64)s.indexOut:?
Int64Index([0,?1,?2,?3,?4],?dtype='int64')當然,我們也可以對索引進行定義,代碼如下:
s=pd.Series([1,2,3,4],index=['a','b','c','d']) sOut:?
a????1 b????2 c????3 d????4在這里,我們將索引定義為a、b、c、d。這時也可以用索引來選取Series的數據,代碼如下:
s['a']Out:
1s[['b','c']]Out:
?
b????2 c????3對Series進行數據運算的時候也會保留索引。示例代碼如下:
s[s>1]Out:?
b????2 c????3 d????4s*3Out:?
a?????3 b?????6 c?????9 d????12Series最重要的功能之一是在不同索引中對齊數據。示例代碼如下:
s1=pd.Series([1,2,3],index=['a','b','c']) s2=pd.Series([4,5,6],index=['b','c','d']) s1+s2Out:?
a???NaN b?????6 c?????8 d???NaNSeries的索引可以通過賦值的方式直接修改,示例代碼如下:
s.indexOut:
Index([u'a',?u'b',?u'c',?u'd'],?dtype='object')s.index=['w','x','y','z'] s.indexOut:?
Index([u'w',?u'x',?u'y',?u'z'],?dtype='object') sOut:?
w????1 x????2 y????3 z????4關于作者:趙志強,金融量化與建模專家,目前在金融科技公司負責金融大數據產品工作,專注于研究Al在金融領域的落地應用。曾在由諾獎得主Robert Engle領導的上海紐約大學波動研究所研究全球金融風險,并和上交所、中金所合作完成多項科研項目。曾在摩根士丹利華鑫基金、明汯投資負責量化投資研究工作,內容包括股票多因子、期貨CTA和高頻交易等。
劉志偉,在中國銀聯云閃付事業部從事數據分析、數據挖掘等工作。對自然語言處理、文本分類、實體識別、關系抽取、傳統機器學習,以及大數據技術棧均有實踐經驗。目前正在探索相關技術在金融場景內的落地應用,包括自動知識圖譜、大規模文本信息抽取結構化、異常識別等領域,關注人工智能行業前沿技術發展。
本文摘編自《Python量化投資:技術、模型與策略》,經出版方授權發布。
延伸閱讀《Python量化投資:技術、模型與策略》
點擊上圖了解及購買
轉載請聯系微信:DoctorData
推薦語:理論與實踐相結合,基于Python闡述量化投資理論和策略,深入分析Python在量化投資分析中具體的應用案例。
劃重點????
干貨直達????
數據從哪里找?手把手教你構建數據集
只有22%的人做對了這道數據分析題,你來試試嗎?
數據中臺:不是產品,不是技術,到底是什么?(附完整PPT下載)
終于有人把網絡爬蟲講明白了
更多精彩????
在公眾號對話框輸入以下關鍵詞
查看更多優質內容!
PPT?|?讀書?|?書單?|?硬核?|?干貨?|?講明白?|?神操作
大數據?|?云計算?|?數據庫?|?Python?|?可視化
AI?|?人工智能?|?機器學習?|?深度學習?|?NLP
5G?|?中臺?|?用戶畫像?|?1024?|?數學?|?算法?|?數字孿生
據統計,99%的大咖都關注了這個公眾號
????
總結
以上是生活随笔為你收集整理的Pandas最详细教程来了!的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 手把手教你用直方图、饼图和条形图做数据分
- 下一篇: 2001~2020大数据行业怎么样?面临