DataFrame
物件的rolling
方法允許我們將資料置於視窗中,然後就可以使用函式對視窗中的資料進行運算和處理。例如,我們獲取了某隻股票近期的資料,想製作5日均線和10日均線,那麼就需要先設定視窗再進行運算。我們可以使用三方庫pandas-datareader
來獲取指定的股票在某個時間段內的資料,具體的操作如下所示。
安裝pandas-datareader
三方庫。
pip install pandas-datareader
透過pandas-datareader
提供的get_data_stooq
從 Stooq 網站獲取百度(股票程式碼:BIDU)近期股票資料。
import pandas_datareader as pdr
baidu_df = pdr.get_data_stooq('BIDU', start='2021-11-22', end='2021-12-7')
baidu_df.sort_index(inplace=True)
baidu_df
輸出:
上面的DataFrame
有Open
、High
、Low
、Close
、Volume
五個列,分別程式碼股票的開盤價、最高價、最低價、收盤價和成交量,接下來我們對百度的股票資料進行視窗計算。
baidu_df.rolling(5).mean()
輸出:
上面的Close
列的資料就是我們需要的5日均線,當然,我們也可以用下面的方法,直接在Close
列對應的Series
物件上計算5日均線。
baidu_df.Close.rolling(5).mean()
輸出:
Date
2021-11-22 NaN
2021-11-23 NaN
2021-11-24 NaN
2021-11-26 NaN
2021-11-29 150.608
2021-11-30 151.014
2021-12-01 150.682
2021-12-02 150.196
2021-12-03 147.062
2021-12-06 146.534
2021-12-07 146.544
Name: Close, dtype: float64
在統計學中,我們通常使用協方差(covariance)來衡量兩個隨機變數的聯合變化程度。如果變數
如果
協方差的數值大小取決於變數的大小,通常是不容易解釋的,但是正態形式的協方差大小可以顯示兩變數線性關係的強弱。在統計學中,皮爾遜積矩相關係數就是正態形式的協方差,它用於度量兩個變數 -1
到1
之間。
估算樣本的協方差和標準差,可以得到樣本皮爾遜係數,通常用希臘字母
我們用
- 判斷指標間是正相關、負相關,還是不相關。
- 當 $ \rho \gt 0 $,認為變數之間是正相關,也就是兩者的趨勢一致。
- 當 $ \rho \lt 0 $,認為變數之間是負相關,也就是兩者的趨勢相反。
- 當 $ \rho = 0 $,認為變數之間是不相關的,但並不代表兩個指標是統計獨立的。
- 判斷指標間的相關程度。
- 當 $ \rho $ 的絕對值在 $ [0.6,1] $ 之間,認為變數之間是強相關的。
- 當 $ \rho $ 的絕對值在 $ [0.1,0.6) $ 之間,認為變數之間是弱相關的。
- 當 $ \rho $ 的絕對值在 $ [0,0.1) $ 之間,認為變數之間沒有相關性。
皮爾遜相關係數適用於:
- 兩個變數之間是線性關係,都是連續資料。
- 兩個變數的總體是正態分佈,或接近正態的單峰分佈。
- 兩個變數的觀測值是成對的,每對觀測值之間相互獨立。
DataFrame
物件的cov
方法和corr
方法分別用於計算協方差和相關係數,corr
方法的第一個引數method
的預設值是pearson
,表示計算皮爾遜相關係數;除此之外,還可以指定kendall
或spearman
來獲得肯德爾係數或斯皮爾曼等級相關係數。
接下來,我們從名為boston_house_price.csv
的檔案中獲取著名的波士頓房價資料集來建立一個DataFrame
,我們透過corr
方法計算可能影響房價的13
個因素中,哪些跟房價是正相關或負相關的,程式碼如下所示。
boston_df = pd.read_csv('data/csv/boston_house_price.csv')
boston_df.corr()
說明:如果需要上面例子中的 CSV 檔案,可以透過下面的百度雲盤地址進行獲取,資料在《從零開始學資料分析》目錄中。連結:https://pan.baidu.com/s/1rQujl5RQn9R7PadB2Z5g_g,提取碼:e7b4。
輸出:
斯皮爾曼相關係數對資料條件的要求沒有皮爾遜相關係數嚴格,只要兩個變數的觀測值是成對的等級評定資料,或者是由連續變數觀測資料轉化得到的等級資料,不論兩個變數的總體分佈形態、樣本容量的大小如何,都可以用斯皮爾曼等級相關係數來進行研究。我們透過下面的方式來計算斯皮爾曼相關係數。
boston_df.corr('spearman')
輸出:
在 Notebook 或 JupyterLab 中,我們可以為PRICE
列新增漸變色,用顏色直觀的展示出跟房價負相關、正相關、不相關的列,DataFrame
物件style
屬性的background_gradient
方法可以完成這個操作,程式碼如下所示。
boston_df.corr('spearman').style.background_gradient('RdYlBu', subset=['PRICE'])
上面程式碼中的RdYlBu
代表的顏色如下所示,相關係數的資料值越接近1
,顏色越接近紅色;資料值越接近1
,顏色越接近藍色;資料值在0
附件則是黃色。
plt.get_cmap('RdYlBu')
我們再來看看Index
型別,它為Series
和DataFrame
物件提供了索引服務,常用的Index
有以下幾種。
程式碼:
sales_data = np.random.randint(400, 1000, 12)
month_index = pd.RangeIndex(1, 13, name='月份')
ser = pd.Series(data=sales_data, index=month_index)
ser
輸出:
月份
1 703
2 705
3 557
4 943
5 961
6 615
7 788
8 985
9 921
10 951
11 874
12 609
dtype: int64
程式碼:
cate_index = pd.CategoricalIndex(
['蘋果', '香蕉', '蘋果', '蘋果', '桃子', '香蕉'],
ordered=True,
categories=['蘋果', '香蕉', '桃子']
)
ser = pd.Series(data=amount, index=cate_index)
ser
輸出:
蘋果 6
香蕉 6
蘋果 7
蘋果 6
桃子 8
香蕉 6
dtype: int64
程式碼:
ser.groupby(level=0).sum()
輸出:
蘋果 19
香蕉 12
桃子 8
dtype: int64
程式碼:
ids = np.arange(1001, 1006)
sms = ['期中', '期末']
index = pd.MultiIndex.from_product((ids, sms), names=['學號', '學期'])
courses = ['語文', '數學', '英語']
scores = np.random.randint(60, 101, (10, 3))
df = pd.DataFrame(data=scores, columns=courses, index=index)
df
說明:上面的程式碼使用了
MultiIndex
的類方法from_product
,該方法透過ids
和sms
兩組資料的笛卡爾積構造了多級索引。
輸出:
語文 數學 英語
學號 學期
1001 期中 93 77 60
期末 93 98 84
1002 期中 64 78 71
期末 70 71 97
1003 期中 72 88 97
期末 99 100 63
1004 期中 80 71 61
期末 91 62 72
1005 期中 82 95 67
期末 84 78 86
程式碼:
# 計算每個學生的成績,期中佔25%,期末佔75%
df.groupby(level=0).agg(lambda x: x.values[0] * 0.25 + x.values[1] * 0.75)
輸出:
語文 數學 英語
學號
1001 93.00 92.75 78.00
1002 68.50 72.75 90.50
1003 92.25 97.00 71.50
1004 88.25 64.25 69.25
1005 83.50 82.25 81.25
-
透過
date_range()
函式,我們可以建立日期時間索引,程式碼如下所示。程式碼:
pd.date_range('2021-1-1', '2021-6-1', periods=10)
輸出:
DatetimeIndex(['2021-01-01 00:00:00', '2021-01-17 18:40:00', '2021-02-03 13:20:00', '2021-02-20 08:00:00', '2021-03-09 02:40:00', '2021-03-25 21:20:00', '2021-04-11 16:00:00', '2021-04-28 10:40:00', '2021-05-15 05:20:00', '2021-06-01 00:00:00'], dtype='datetime64[ns]', freq=None)
程式碼:
pd.date_range('2021-1-1', '2021-6-1', freq='W')
輸出:
DatetimeIndex(['2021-01-03', '2021-01-10', '2021-01-17', '2021-01-24', '2021-01-31', '2021-02-07', '2021-02-14', '2021-02-21', '2021-02-28', '2021-03-07', '2021-03-14', '2021-03-21', '2021-03-28', '2021-04-04', '2021-04-11', '2021-04-18', '2021-04-25', '2021-05-02', '2021-05-09', '2021-05-16', '2021-05-23', '2021-05-30'], dtype='datetime64[ns]', freq='W-SUN')
-
透過
DateOffset
型別,我們可以設定時間差並和DatetimeIndex
進行運算,具體的操作如下所示。程式碼:
index = pd.date_range('2021-1-1', '2021-6-1', freq='W') index - pd.DateOffset(days=2)
輸出:
DatetimeIndex(['2021-01-01', '2021-01-08', '2021-01-15', '2021-01-22', '2021-01-29', '2021-02-05', '2021-02-12', '2021-02-19', '2021-02-26', '2021-03-05', '2021-03-12', '2021-03-19', '2021-03-26', '2021-04-02', '2021-04-09', '2021-04-16', '2021-04-23', '2021-04-30', '2021-05-07', '2021-05-14', '2021-05-21', '2021-05-28'], dtype='datetime64[ns]', freq=None)
程式碼:
index + pd.DateOffset(days=2)
輸出:
DatetimeIndex(['2021-01-05', '2021-01-12', '2021-01-19', '2021-01-26', '2021-02-02', '2021-02-09', '2021-02-16', '2021-02-23', '2021-03-02', '2021-03-09', '2021-03-16', '2021-03-23', '2021-03-30', '2021-04-06', '2021-04-13', '2021-04-20', '2021-04-27', '2021-05-04', '2021-05-11', '2021-05-18', '2021-05-25', '2021-06-01'], dtype='datetime64[ns]', freq=None)
-
可以使用
DatatimeIndex
型別的相關方法來處理資料,具體包括:-
shift()
方法:透過時間前移或後移資料,我們仍然以上面百度股票資料為例,程式碼如下所示。程式碼:
baidu_df.shift(3, fill_value=0)
輸出:
程式碼:
baidu_df.shift(-1, fill_value=0)
輸出:
-
asfreq()
方法:指定一個時間頻率抽取對應的資料,程式碼如下所示。程式碼:
baidu_df.asfreq('5D')
輸出:
程式碼:
baidu_df.asfreq('5D', method='ffill')
輸出:
-
resample()
方法:基於時間對資料進行重取樣,相當於根據時間週期對資料進行了分組操作,程式碼如下所示。程式碼:
baidu_df.resample('1M').mean()
輸出:
說明:上面的程式碼中,
W
表示一週,5D
表示5
天,1M
表示1
個月。 -
-
時區轉換