1. 程式人生 > >量化交易入門筆記-Pandas庫

量化交易入門筆記-Pandas庫

Pandas 是基於 Numpy 構建的,讓以 Numpy 為中心的應用變得更加簡單

Pandas 提供了大量快速便捷地處理資料的函式和方法,這也是使 Pandas 成為強大的高效的資料分析環境的重要因素之一

Pandas 的資料結構主要有三種

  • Series
  • DataFrame
  • Panel

一維陣列 Series

Series 是由一組資料(各種 Numpy 資料型別),以及一組與之相關的標籤資料(即索引)組成。僅上一組資料即可產生最簡單的 Series,也可以通過傳遞一個 list 物件來建立一個 Series 。需要注意的是,Pandas 會預設建立整形索引

Series 中只允許在座相同型別的資料,以提高運算效率

# 引用 pandas 庫,並重命名為 pd
import pandas as pd

pd_series = pd.Series(['Python','C','C#','C++','Java','VB','VC'])
print("顯示Series中的內容\n", pd_series)
print("顯示Series中的索引\n", pd_series.index)
print("顯示Series中的資料\n", pd_series.values)

# 建立帶指定索引的Serices
other_series = pd.Series(['Python','C','C#','C++','Java'
,'VB','VC'], index = ['a','b','c','d','e','f','g']) print("顯示Series中的內容\n:", other_series)
顯示Series中的內容
 0    Python
1         C
2        C#
3       C++
4      Java
5        VB
6        VC
dtype: object
顯示Series中的索引
 Int64Index([0, 1, 2, 3, 4, 5, 6], dtype='int64')
顯示Series中的資料
 ['Python' 'C' 'C#' 'C++' 'Java' 'VB' 'VC']
顯示Series中的內容:
a    Python
b         C
c        C#
d       C++
e      Java
f        VB
g        VC
dtype: object

二維陣列 DataFrame

DataFrame 是一個表格型資料結構,它含有一組有序的列,每一列的資料結構都是相同的,而不同列之間則可以是不同的資料型別。或者以資料庫進行型別,DataFrame 中的每一行是一個記錄,名稱為 Index 的一個元素,而每一列則為一個欄位,是這個記錄的一個屬性。DataFrame 既有行的索引也有列的索引,可以被看作由 Series 組成的字典(共用一個索引)

DataFrame 是個二維陣列,相當於表結構。它的列稱為columns,行稱為index。也可以將DataFrame理解為Series的容器

建立 DataFrame

# 引用 pandas 庫,並重命名為 pd
import pandas as pd

data = {"name":["yahoo", "google", "facebook"], "marks": [200,400,800], "price": [9, 3, 7]}
pd_dataframe = pd.DataFrame(data)
print("顯示DataFrame的資料")
print(pd_dataframe)
顯示DataFrame的資料
   marks      name  price
0    200     yahoo      9
1    400    google      3
2    800  facebook      7

提示,因為字典是無序的,所以最後轉換成DataFrame後,列的順序可能與定義的時候是不一樣的

檢視資料

先利用get_price函式來獲取某股票一段時間內的資料,其語法如下:

get_price(security, start_date=None, end_date=None, frequency='daily', fields=None, skip_paused=False, fq='pre', count=None)

引數解析:

  • security:一隻股票的程式碼或一組股票程式碼的 list

  • start_date: 開始時間,與引數 count 二選一,不可同時使用。如果兩者都沒有設定,則start_date生效,預設時間為’2015-01-01’。如果取分鐘資料,時間可以精確到分鐘

  • end_date: 結束時間,預設是’2015-12-31’,包含此日期。當取分鐘資料時,如果只有日期,則日內時間等同於’00:00:00’,所以返回的資料不包括 end_date 這一天

  • frequency: 單位時間長度,幾天或者幾分鐘,預設是 daily ,即表示1天。現在支援

    • Xd 幾天
    • Xm 幾月
    • daily 1天
    • minute 1分鐘

    需要注意的是,當X>1時,fields 只支援 [‘open’, ‘close’, ‘high’, ‘low’, ‘volume’, ‘money’] 這幾個標準欄位

  • fields: 字串 list,選擇要獲取的行情資料欄位,預設是 None(表示 [‘open’, ‘close’, ‘high’, ‘low’, ‘volume’, ‘money’] 這幾個標準欄位)。引數 felids 支援 SecurityUnitData 裡面的所有基本屬性,包含:[‘open’, ‘close’, ‘high’, ‘low’, ‘volume’, ‘money’, ‘factor’, ‘high_limit’, ‘low_limit’, ‘avg’, ‘pre_close’, ‘paused’]

  • sikp_paused:是否跳過不易日期(包括停牌、未上市或者退市後資料者為 nan。需要注意的是,該引數預設為 False ,即不跳過不交易日期。如果當該引數是 True 時,只能選取一隻股票的資訊

  • fq: 復權選項。引數值設為 ‘pre’,表示前復權,為預設設定;引數值為 None,表示不復權,返回實際價格;引數值設定為 ‘post’,表示後復權

  • count:與 start_date 二選一,不可同時使用。引數 count 表示數量,返回結果集的行數,表示獲取 end_date 之前幾個 frequency 的資料

示例程式碼:

# 引用 pandas 庫,並重命名為 pd
import pandas as pd

# 通過get_price函式獲取一段時間內某股票的資料
date_frame = get_price('000009.XSHE', 
                       start_date='2018-04-03', 
                       end_date='2018-04-20', frequency='daily')
date_frame
open close high low volume money
2018-04-03 5.97 6.17 6.20 5.88 32328739 1.964467e+08
2018-04-04 6.14 6.24 6.30 6.12 28622962 1.778433e+08
2018-04-09 6.24 6.33 6.33 6.15 29313979 1.832740e+08
2018-04-10 6.32 6.26 6.33 6.16 25122114 1.565214e+08
2018-04-11 6.27 6.21 6.27 6.20 13808473 8.598230e+07
2018-04-12 6.23 6.24 6.28 6.17 17397725 1.082082e+08
2018-04-13 6.23 6.11 6.27 6.09 17134280 1.056886e+08
2018-04-16 6.26 6.26 6.48 6.22 35419584 2.233821e+08
2018-04-17 6.26 6.01 6.26 6.01 23077057 1.411712e+08
2018-04-18 6.05 6.09 6.12 5.90 14690685 8.846467e+07
2018-04-19 6.06 6.08 6.23 6.06 13842257 8.486182e+07
2018-04-20 6.04 5.98 6.11 5.95 12086284 7.270285e+07

另外date_frame.head()可以只顯示前五行資料:

# 引用 pandas 庫,並重命名為 pd
import pandas as pd

# 通過get_price函式獲取一段時間內某股票的資料
date_frame = get_price('000009.XSHE', 
                       start_date='2018-04-03', 
                       end_date='2018-04-20', frequency='daily')
date_frame.head()
open close high low volume money
2018-04-03 5.97 6.17 6.20 5.88 32328739 1.964467e+08
2018-04-04 6.14 6.24 6.30 6.12 28622962 1.778433e+08
2018-04-09 6.24 6.33 6.33 6.15 29313979 1.832740e+08
2018-04-10 6.32 6.26 6.33 6.16 25122114 1.565214e+08
2018-04-11 6.27 6.21 6.27 6.20 13808473 8.598230e+07

顯示最後五行資料,可以使用date_frame.tail()

# 引用 pandas 庫,並重命名為 pd
import pandas as pd

# 通過get_price函式獲取一段時間內某股票的資料
date_frame = get_price('000009.XSHE', 
                       start_date='2018-04-03', 
                       end_date='2018-04-20', frequency='daily')
date_frame.tail()
open close high low volume money
2018-04-16 6.26 6.26 6.48 6.22 35419584 2.233821e+08
2018-04-17 6.26 6.01 6.26 6.01 23077057 1.411712e+08
2018-04-18 6.05 6.09 6.12 5.90 14690685 8.846467e+07
2018-04-19 6.06 6.08 6.23 6.06 13842257 8.486182e+07
2018-04-20 6.04 5.98 6.11 5.95 12086284 7.270285e+07

選擇資料

只顯示開盤價(open)的資料資訊,如下:

# 引用 pandas 庫,並重命名為 pd
import pandas as pd

# 通過get_price函式獲取一段時間內某股票的資料
date_frame = get_price('000009.XSHE', 
                       start_date='2018-04-03', 
                       end_date='2018-04-20', frequency='daily')
date_frame['open']
2018-04-03    5.97
2018-04-04    6.14
2018-04-09    6.24
2018-04-10    6.32
2018-04-11    6.27
2018-04-12    6.23
2018-04-13    6.23
2018-04-16    6.26
2018-04-17    6.26
2018-04-18    6.05
2018-04-19    6.06
2018-04-20    6.04
Name: open, dtype: float64

選擇多個欄位,如下:

# 引用 pandas 庫,並重命名為 pd
import pandas as pd

# 通過get_price函式獲取一段時間內某股票的資料
date_frame = get_price('000009.XSHE', 
                       start_date='2018-04-03', 
                       end_date='2018-04-20', frequency='daily')
date_frame[['open', 'close', 'money']]  # 開盤價、收盤價、成交額
open close money
2018-04-03 5.97 6.17 1.964467e+08
2018-04-04 6.14 6.24 1.778433e+08
2018-04-09 6.24 6.33 1.832740e+08
2018-04-10 6.32 6.26 1.565214e+08
2018-04-11 6.27 6.21 8.598230e+07
2018-04-12 6.23 6.24 1.082082e+08
2018-04-13 6.23 6.11 1.056886e+08
2018-04-16 6.26 6.26 2.233821e+08
2018-04-17 6.26 6.01 1.411712e+08
2018-04-18 6.05 6.09 8.846467e+07
2018-04-19 6.06 6.08 8.486182e+07
2018-04-20 6.04 5.98 7.270285e+07

顯示第四條到第六條資訊

# 引用 pandas 庫,並重命名為 pd
import pandas as pd

# 通過get_price函式獲取一段時間內某股票的資料
date_frame = get_price('000009.XSHE', 
                       start_date='2018-04-03', 
                       end_date='2018-04-20', frequency='daily')
date_frame[3:6] 
open close high low volume money
2018-04-10 6.32 6.26 6.33 6.16 25122114 1.565214e+08
2018-04-11 6.27 6.21 6.27 6.20 13808473 8.598230e+07
2018-04-12 6.23 6.24 6.28 6.17 17397725 1.082082e+08

使用標籤選取資料,語法如下:

date_frame.loc[行標籤, 列標籤]

# 選擇a行到b行
date_frame.loc['a':'b']
# 選擇open列的所有資料
date_frame.loc[:, 'open']

可以看出,第一個引數表示行標籤,逗號後的第二個引數表示的是列標籤,當然,如果沒有第二個引數的話則選擇所有列

兩個引數既可以是列表,也可以是單個字元,如果兩個引數都為列表,則返回的是DataFrame,否則返回Series

loc為location縮寫

選擇某一天的資料

# 引用 pandas 庫,並重命名為 pd
import pandas as pd

# 通過get_price函式獲取一段時間內某股票的資料
date_frame = get_price('000009.XSHE', 
                       start_date='2018-04-03', 
                       end_date='2018-04-20', frequency='daily')
date_frame.loc['2018-04-10']
open      6.320000e+00
close     6.260000e+00
high      6.330000e+00
low       6.160000e+00
volume    2.512211e+07
money     1.565214e+08
Name: 2018-04-10 00:00:00, dtype: float64

選擇某一天的收盤價資料

# 引用 pandas 庫,並重命名為 pd
import pandas as pd

# 通過get_price函式獲取一段時間內某股票的資料
date_frame = get_price('000009.XSHE', 
                       start_date='2018-04-03', 
                       end_date='2018-04-20', frequency='daily')
date_frame.loc['2018-04-10', 'close']
6.2599999999999998

選擇某一時間段的收盤價資料

# 引用 pandas 庫,並重命名為 pd
import pandas as pd

# 通過get_price函式獲取一段時間內某股票的資料
date_frame = get_price('000009.XSHE', 
                       start_date='2018-04-03', 
                       end_date='2018-04-20', frequency='daily')
date_frame.loc['2018-04-10':'2018-04-18', 'close']
2018-04-10    6.26
2018-04-11    6.21
2018-04-12    6.24
2018-04-13    6.11
2018-04-16    6.26
2018-04-17    6.01
2018-04-18    6.09
Name: close, dtype: float64

選擇所有日期下的收盤價資料

# 引用 pandas 庫,並重命名為 pd
import pandas as pd

# 通過get_price函式獲取一段時間內某股票的資料
date_frame = get_price('000009.XSHE', 
                       start_date='2018-04-03', 
                       end_date='2018-04-20', frequency='daily')
date_frame.loc[:, 'close']
2018-04-03    6.17
2018-04-04    6.24
2018-04-09    6.33
2018-04-10    6.26
2018-04-11    6.21
2018-04-12    6.24
2018-04-13    6.11
2018-04-16    6.26
2018-04-17    6.01
2018-04-18    6.09
2018-04-19    6.08
2018-04-20    5.98
Name: close, dtype: float64

使用位置選取資料,語法如下:

df.iloc[行位置, 列位置]

# 選取第二行,第二列的值,返回的為單個值
df.iloc[1, 1]
# 選取第一行及第三行的資料(包含第三行)
df.iloc[[0, 2], :]
# 選取第一行到第三行的資料(不包含第三行)
df.iloc[0:2, :]
# 選取所有記錄的第二列值,返回的為 Series
df.iloc[:, 1]
# 選取第一行資料,返回為 Series
df.iloc[0, :]

iloc 是 integer 與 location 的縮寫

顯示第三行第四列的值

# 引用 pandas 庫,並重命名為 pd
import pandas as pd

# 通過get_price函式獲取一段時間內某股票的資料
date_frame = get_price('000009.XSHE', 
                       start_date='2018-04-03', 
                       end_date='2018-04-20', frequency='daily')
date_frame.iloc[2,3]
6.1500000000000004

更廣義的切片方式是使用.ix,它自動根據給到的索引型別判斷是使用位置還是標籤進行切片,語法如下:

df.ix[1,1]
df.ix['a':'b']

顯示第二行的開盤價

# 引用 pandas 庫,並重命名為 pd
import pandas as pd

# 通過get_price函式獲取一段時間內某股票的資料
date_frame = get_price('000009.XSHE', 
                       start_date='2018-04-03', 
                       end_date='2018-04-20', frequency='daily')
date_frame.ix[1,'open']
6.1399999999999997

通過邏輯指標進行資料切片,語法如下:

df[邏輯條件]
df[df.one >= 2]  # 單個邏輯條件
df[(df.one >=1) & (df.one < 3)]  # 多個邏輯條件組合 

顯示收盤價大於6.25的資料資訊

# 引用 pandas 庫,並重命名為 pd
import pandas as pd

# 通過get_price函式獲取一段時間內某股票的資料
date_frame = get_price('000009.XSHE', 
                       start_date='2018-04-03', 
                       end_date='2018-04-20', frequency='daily')
date_frame[date_frame.close > 6.25]
open close high low volume money
2018-04-09 6.24 6.33 6.33 6.15 29313979 1.832740e+08
2018-04-10 6.32 6.26 6.33 6.16 25122114 1.565214e+08
2018-04-16 6.26 6.26 6.48 6.22 35419584 2.233821e+08

顯示收盤價大於6.25並且成交量小於26000000的資料資訊

# 引用 pandas 庫,並重命名為 pd
import pandas as pd

# 通過get_price函式獲取一段時間內某股票的資料
date_frame = get_price('000009.XSHE', 
                       start_date='2018-04-03', 
                       end_date='2018-04-20', frequency='daily')
date_frame[(date_frame.close > 6.25) & (date_frame.volume < 26000000)]
open close high low volume money
2018-04-10 6.32 6.26 6.33 6.16 25122114 1.565214e+08

使用條件更改資料,如將大於6.25的資料都改為0

# 引用 pandas 庫,並重命名為 pd
import pandas as pd

# 通過get_price函式獲取一段時間內某股票的資料
date_frame = get_price('000009.XSHE', 
                       start_date='2018-04-03', 
                       end_date='2018-04-20', frequency='daily')
date_frame[(date_frame.close > 6.25)] = 0
date_frame
open close high low volume money
2018-04-03 5.97 6.17 6.20 5.88 32328739 1.964467e+08
2018-04-04 6.14 6.24 6.30 6.12 28622962 1.778433e+08
2018-04-09 0.00 0.00 0.00 0.00 0 0.000000e+00
2018-04-10 0.00 0.00 0.00 0.00 0 0.000000e+00
2018-04-11 6.27 6.21 6.27 6.20 13808473 8.598230e+07
2018-04-12 6.23 6.24 6.28 6.17 17397725 1.082082e+08
2018-04-13 6.23 6.11 6.27 6.09 17134280 1.056886e+08
2018-04-16 0.00 0.00 0.00 0.00 0 0.000000e+00
2018-04-17 6.26 6.01 6.26 6.01 23077057 1.411712e+08
2018-04-18 6.05 6.09 6.12 5.90 14690685 8.846467e+07
2018-04-19 6.06 6.08 6.23 6.06 13842257 8.486182e+07
2018-04-20 6.04 5.98 6.11 5.95 12086284 7.270285e+07

資料的處理

利用函式 mean()計算列的平均值

# 引用 pandas 庫,並重命名為 pd
import pandas as pd

# 通過get_price函式獲取一段時間內某股票的資料
date_frame = get_price('000009.XSHE', 
                       start_date='2018-04-03', 
                       end_date='2018-04-20', frequency='daily')
date_frame.mean()
open      6.172500e+00
close     6.165000e+00
high      6.265000e+00
low       6.075833e+00
volume    2.190368e+07
money     1.353789e+08
dtype: float64

利用函式 mean()計算行的平均值

# 引用 pandas 庫,並重命名為 pd
import pandas as pd

# 通過get_price函式獲取一段時間內某股票的資料
date_frame = get_price('000009.XSHE', 
                       start_date='2018-04-03', 
                       end_date='2018-04-20', frequency='daily')
date_frame.mean(1)
2018-04-03    38129240.208333
2018-04-04    34411055.211667
2018-04-09    35431328.273333
2018-04-10    30273916.950000
2018-04-11    16631799.603333
2018-04-12    20934324.403333
2018-04-13    20470484.040000
2018-04-16    43133625.271667
2018-04-17    27374717.911667
2018-04-18    17192562.471667
2018-04-19    16450684.143333
2018-04-20    14131525.563333
dtype: float64

可以看出,mean()如果有引數,計算的是列,如果引數是1,計算的是行

三維陣列

如果要獲取多隻股票的資料,則返回panle物件;可以通過panle[列標, 行標, 股票程式碼]來獲取資料

# 引用 pandas 庫,並重命名為 pd
import pandas as pd

# 通過get_price函式獲取一段時間內某股票的資料
date_frame = get_price(['000009.XSHE', '000001.XSHE'], 
                       start_date='2018-04-03', 
                       end_date='2018-04-20', 
                       frequency='daily')
date_frame
<class 'pandas.core.panel.Panel'>
Dimensions: 6 (items) x 12 (major_axis) x 2 (minor_axis)
Items axis: close to volume
Major_axis axis: 2018-04-03 00:00:00 to 2018-04-20 00:00:00
Minor_axis axis: 000009.XSHE to 000001.XSHE

對這個輸出結果的解析:

  • Items axis: close to volume - 列標
  • Major_axis axis: 2018-04-03 00:00:00 to 2018-04-20 00:00:00 - 行標
  • Minor_axis axis: 000009.XSHE to 000001.XSHE - 股票程式碼

顯示兩隻股票的收盤價資訊

# 引用 pandas 庫,並重命名為 pd
import pandas as pd

# 通過get_price函式獲取一段時間內某股票的資料
date_frame = get_price(['000009.XSHE', '000001.XSHE'], 
                       start_date='2018-04-03', 
                       end_date='2018-04-20', 
                       frequency='daily')
date_frame['close',:,:]
000009.XSHE 000001.XSHE
2018-04-03 6.17 10.40
2018-04-04 6.24 10.71
2018-04-09 6.33 10.85
2018-04-10 6.26 11.25
2018-04-11 6.21 11.65
2018-04-12 6.24 11.35
2018-04-13 6.11 11.40
2018-04-16 6.26 10.93
2018-04-17 6.01 11.04
2018-04-18 6.09 11.33
2018-04-19 6.08 11.30
2018-04-20 5.98 11.18

顯示兩隻股票2018年4月16日的資料資訊

# 引用 pandas 庫,並重命名為 pd
import pandas as pd

# 通過get_price函式獲取一段時間內某股票的資料
date_frame = get_price(['000009.XSHE', '000001.XSHE'], 
                       start_date='2018-04-03', 
                       end_date='2018-04-20', 
                       frequency='daily')
date_frame[:,'2018-04-16',:]
close high low money open volume
000009.XSHE 6.26 6.48 6.22 2.233821e+08 6.26 35419584
000001.XSHE 10.93 11.30 10.86 1.593706e+09 11.30 144892608

顯示平安銀行000001.XSHE的資料資訊

# 引用 pandas 庫,並重命名為 pd
import pandas as pd

# 通過get_price函式獲取一段時間內某股票的資料
date_frame = get_price(['000009.XSHE', '000001.XSHE'], 
                       start_date='2018-04-03', 
                       end_date='2018-04-20', 
                       frequency='daily')
date_frame[:,:,'000001.XSHE']
close high low money open volume
2018-04-03 10.40 10.51 10.35 9.422378e+08 10.44 90438595
2018-04-04 10.71 10.84 10.44 1.737259e+09 10.52 162702821
2018-04-09 10.85 10.93 10.57 1.180084e+09 10.64 109125449
2018-04-10 11.25 11.29 10.80 1.562265e+09 10.85 141225091
2018-04-11 11.65 11.74 11.21 2.458982e+09 11.22 212806679
2018-04-12 11.35 11.65 11.25 1.364676e+09 11.62 119109271
2018-04-13 11.40 11.61 11.28 1.516156e+09 11.46 132016725
2018-04-16 10.93 11.30 10.86 1.593706e+09 11.30 144892608
2018-04-17 11.04 11.28 10.94 1.468159e+09 10.95 132182805
2018-04-18 11.33 11.43 11.11 1.692723e+09 11.28 149844547
2018-04-19 11.30 11.51 11.25 9.795936e+08 11.35 86213489
2018-04-20 11.18 11.41 11.03 1.090801e+09 11.34 97337143

注:本文章為個人學習筆記,參考了一些書籍與官方教程,不作任何商業用途!