Try   HackMD

輕鬆學會程式交易 | Chapter 3 | Pandas

3-1 什麼是Pandas

pandas is a fast, powerful, flexible and easy to use open source data analysis and manipulation tool,
built on top of the Python programming language.
Pandas

Pandas 是個快速、強大、有彈性並且易使用的開源資料分析及操作工具,基於python程式語言
Pandas官網標題

下載套件

請在 Ipython Console 中輸入以下兩行程式下,即可下載

pip install pandas # pandas套件 pip install pandas_datareader # pandas 擴充套件,下載數據專用

3-2 DataFrame 和 Series

pandas中有個最重要的變數型態叫作DataFrame。我們直接叫一個DataFrame出來具體的介紹一下它。
首先我們先從檔案匯入台積電的日線資料。

開啟檔案/下載資料

呼叫及使用套件。尾端使用as即可替套件重新取名字。

import pandas as pd

請注意:檔案與程式碼需在同一個資料夾

  1. 開啟csv
    pd.read_csv是一個函式,功能是讀取一個.csv檔案並且用DataFrame的變數型態表示它。
twic = pd.read_csv('2330twic.csv', index_col='DATE')
  1. 或從Excel檔案中開啟
    簡單一行開啟,是不是很方便呀!
twic = pd.read_excel('2330twic.xlsx', index_col='DATE')
  1. 使用pandas_datareader套件下載股價資料
# pip install pandas_datareader import pandas_datareader as pdr twic = pdr.DataReader('2330.TW','yahoo')

這時候就可以在spyder裡面的variable navigator看到我們匯入的資料了。
我接下來要介紹一下這個DataFrame。

DataFrame有直行橫列,最上方的這一橫排標示著這每一行的名稱,最左方的這一直列標示每一列的index(編號)。

  1. 可以用columns屬性得到所有行的名稱
  2. shape屬性得到DataFrame的形狀(大小)。
  3. len()函式來得到rows的數量
print(twic.shape) print(twic.columns) print(len(twic))
out: (1220, 6)
out: Index(['High', 'Low', 'Open', 'Close', 'Volume', 'Adj Close'], dtype='object')
out: 1220

存取數據、切片

存取columns

pandas在存取每個column的時候,是採取很像字典的方式,透過字串去索引。在製造一個新的column時,也事像,字典一樣直接宣告即可

我們把twic DataFrame的'OPEN' column取出來,另外存到twic_open這個新的變數裡。

twic_open = twic['Open'] print(twic_open)

使用iloc(位置呼叫)

我們也可以使用DataFrame的iloc來存取DataFrame裡面的資料。
iloc意思是 integer location(整數位置),就是把DataFrame裡面的窗格做編號,用[列,行]的順序存取。
記得,數數是從0開始。

print(twic.iloc[12,4]) print(twic.iloc[:,4]) print(twic.iloc[12])

切片 slice

你也可以用iloc來做切片,就如同前面對列表做的一樣。

#最近五十天的開高低收 print(twic.iloc[0:50,1:5])

Series

Series構成DataFrame

試著印出twic_open的type,會發現他是一個叫作Series(意為序列)的變數型態,你可以想像,就是這一行一行的Series組合成一個DataFrame。

print(type(twic_open))
twic['new_column'] = 0 print(twic)

數學運算

相同長度的Series可以互相做運算,很常見的像是加減乘除。運算結果會得到一個新的Series。

程式碼->twic['漲跌'] 會在twic DataFrame中新增欄位,並取名為"漲跌"

twic_open = twic['OPEN'] twic_close = tiwc['CLOSE'] twic['漲跌'] = twic_close - twic_open twic['漲跌幅'] = (twic_close - twic_open) / twic_open

那請問如果我們將每日的收盤價減去開盤價,我們得到的這個新的series代表什麼意思?
Ans: 日K線的長度,負號代表黑K。

成員函式

max, min, mean
print(twic_open.max())
print(twic_open.min())
print(twic_open.mean())
pct_change

拿來計算成長率

print(twic_open.pct_change(periods=1))
print(twic_open.pct_change(periods=2))

3-3 DataFrame 操作

命名、更新

直接重新命名

twic.columns = ['open','high','low','close','adj_close','volume'] print(twic)

也可以用DataFrame的rename方法。

twic = pd.read_csv('2330twic.csv', index_col='Date') twic = twic.rename(columns={'High': 'HIGH'}) print(twic.columns)

合併、插入、拼接

merge

  • 下載數據
import pandas_datareader as pdr # 加權指數 twii = pdr.DataReader('^TWII','yahoo',start='2000') # 0050台灣五十 price_0050 = pdr.DataReader('0050.TW','yahoo',start='2000')
  • 合併數據
    使用index索引合併請使用left_index=True
    使用column名稱合併請使用left_on='xx'(ex:"Date")
merged = pd.merge(twii, price_0050, left_index=True, right_on='Date') print(merged.columns)

有名稱一樣的columns,pandas會自動的標上_x,_y 作為後綴。我們也可以自己設定。

merged = pd.merge(twii, price_0050, left_on='Date', right_on='Date', suffixes = ('_twii','_0050')) print(merged.columns)

append

往下append

twii = pdr.DataReader('^TWII','yahoo')

ignore_index· : 重新排序index
sort : 對columns排序

df1 = twii[:"2017"] df2 = twii["2018":] df1.append(df2, ignore_index=True, sort=False)

join

往右join

joined = twii.join(price_0050,rsuffix='_0050')

shift

正數代表往下平移,負號代表往上平移

twic.shift(1)
twic.shift(-3)

也可以對Series做。

twic_close.shift(1)
twic_close - twic_close.shift(1)

這樣可以得到收盤價對前一天的漲跌

3-4 分組與滾動處理

rolling

rolling是一個移動窗格的概念,將一個DataFrame的橫列N個作為一組。再來就可以接上我們想要的操作,最常用的max, min, mean等。
我們試試看用rolling().mean()來做移動平均線。

close = twic['Close'] ma_5 = close.rolling(5).mean() twic['CLOSE_MA_5D'] = ma_5

破新高

close = twic['Close'] # close = twic.Close max_20 = close.rolling(20).max() is_new_price = (max_20 == twic['ADJ_CLOSE']) twic['IS_NEW_PRICE'] = is_new_price

groupby

groupby可以以某個欄位或者Series進行分組,為了方便學習,我們使用for迴圈的方式進行拆解。

twic.index = pd.to_datetime(twic.index) groups = twic.groupby([twic.index.year, twic.index.month]) for group, frame_window in groups: print(group) print(frame_window) print('open:', frame_window.iloc[0,0]) print('high:', frame_window['High'].max()) print('low:', frame_window['Low'].min()) print('close:', frame_window.iloc[-1,3])

更好、更快的方法

twic.groupby([twic.index.year,twic.index.month])["Close"].ohlc()

3-5 apply

apply

這個功能極為重要,請多試試

def add2(x): return x + 2 twic_open.apply(add2)

3-6 第二次作業

  • 下載0056及0050資料
  • 將兩資料的“調整日收盤價”轉成“月調整收盤價”資料
  • 將兩資料轉成起始為100的權益並用plot函數畫出