1. 程式人生 > >pandas 常用內建函式整理

pandas 常用內建函式整理

pct_change()

           計算百分比變化。

cov()

         計算協方差。其中用到了內建函式 concat,它是以 Series 物件組成的列表為輸出,當引數 axis 的值為 1 的時候把他們一行一行從左到右的組合成一個 DataFrame 的物件,。然後使用方法 cov 得到這三個行之間的一個相關矩陣。

import pandas as pd
import matplotlib.pyplot as plt

stock1 = pd.read_excel('sz50.xlsx',sheet_name = '600036.XSHG', index_col = 'datetime')
stock2 = pd.read_excel('sz50.xlsx',sheet_name = '600050.XSHG', index_col = 'datetime')
stock3 = pd.read_excel('sz50.xlsx',sheet_name = '601318.XSHG', index_col = 'datetime')

five_day_df = pd.concat([stock1.close.pct_change(5), stock2.close.pct_change(5), stock3.close.pct_change(5)], keys = ['stock1', 'stock2', 'stock3'], axis = 1)

print(five_day_df.cov())

          在整個 DataFrame 物件中每一列,每個 Series 物件中含有 nan 無效值時,使用 cov 並不會失敗,pandas 用了一種估計的方法來解決這個無效值,並不是簡單地用某個固定的值替代,具體參考文章如下,把教程中的任務完成就會來解決這個點。

corr()

          計算相關係數矩陣,得到的依然是一個 DataFrame 物件。

import pandas as pd
import matplotlib.pyplot as plt

stock1 = pd.read_excel('sz50.xlsx',sheet_name = '600036.XSHG', index_col = 'datetime')
stock2 = pd.read_excel('sz50.xlsx',sheet_name = '600050.XSHG', index_col = 'datetime')
stock3 = pd.read_excel('sz50.xlsx',sheet_name = '601318.XSHG', index_col = 'datetime')

five_day_df = pd.concat([stock1.close.pct_change(5), stock2.close.pct_change(5), stock3.close.pct_change(5)], keys = ['stock1', 'stock2', 'stock3'], axis = 1)

print(five_day_df.corr())

         corr 和 cov 還有一個更基礎的用法就是用在單獨的 Series 物件上,在 cov 或者 corr 中填入想要比較的另一個 Series 物件。

stock1.close.pct_change()[1:].cov(stock2.close.pct_change[1:])

stock1.close.pct_change()[1:].corr(stock2.close.pct_change[1:])

       當然以上的方法要求 Series 物件的長度相同,不然無法匹配。那麼如果是 DataFrame 物件,通過預設值為 1 表示列(0 表示行)的引數 axis ,那麼會匹配兩個物件中 columns 的值相同的列,例如以下程式碼:

import pandas as pd
import numpy as np

frame1 = pd.DataFrame(np.random.randn(5, 4), index = ['1','2','3','4','5'], columns = ['a', 'b', 'c', 'd'])
frame2 = pd.DataFrame(np.random.randn(4, 4), index = frame1.index[:4], columns = ['a', 'b', 'c', 'd'])
print(frame1.corrwith(frame2))
print(frame2.corrwith(frame1))

結果:
a   -0.732968
b   -0.246053
c    0.022138
d   -0.612281
dtype: float64
a   -0.732968
b   -0.246053
c    0.022138
d   -0.612281
dtype: float64

          如果是直接 frame1.corr(frame2) 會報錯但報錯內容不是很直接地指出我們這個問題,報錯內容為

TypeError: Could not compare ['pearson'] with block values

pearson 代表的是 standard correlation coefficient也就是最常見最基礎的相關係數的計算方式,因為 DataFrame 物件的 corr 與 Series 物件的 corr 不同,DataFrame 的 corr 接受兩個引數 method 和 min_period,method:{‘pearson’, ‘kendall’, ‘spearman’},所以才會報錯個什麼 pearson。

rank()

         排序。得到了每個位置上的資料在該列中的排序的序號,預設的有兩個引數,axis 預設為 0 表示按列排序,ascending 為 True 表示升序排列即數值為大排名越靠後(序號越大)。如果資料中有無效值,那麼得到的排序相應的位置呈現為 nan,其他的正常資料不受影響。

import pandas as pd
import matplotlib.pyplot as plt

stock1 = pd.read_excel('sz50.xlsx',sheet_name = '600036.XSHG', index_col = 'datetime')
stock2 = pd.read_excel(‘sz50.xlsx',sheet_name = '600050.XSHG', index_col = 'datetime')
stock3 = pd.read_excel('sz50.xlsx',sheet_name = '601318.XSHG', index_col = 'datetime')

five_day_df = pd.concat([stock1.close.pct_change(5), stock2.close.pct_change(5), stock3.close.pct_change(5)], keys = ['stock1', 'stock2', 'stock3'], axis = 1)

part = five_day_df.tail()
print(part)
print(part.rank())

rolling()

        滾動計算。滾動視窗計算的意思是我圍繞一個點,用一個確定長度的窗體 window 包含最近一段時間的資料。例如有如下的資料,設窗體的尺度為3,那麼 index 為 3 的資料對應的為 [3,5,4].

index

1

3
2 5
3 4
4 7
5 3

得到 roling 物件之後不能直接整個內容輸出,而是要根據需要呼叫相應的方法。例如 sum,求和;mean,求平均,在官方文件中有相關方法的集合如下。

         以如下的程式碼為例子,可以看出設 window 為 4 時前三個空為零,因為預設的另一個引數 min_period 會等於 window,當然我們可以設定得小於 window 那樣子就會使得不必每個窗體都必須有 4 個物件,3個或者更少也沒問題。還有引數 center 預設為 False,也就是我們獲取當前點為最後一個值的一個箱體,如果 center 設定為 True 就會把我們獲取的當前點作為中點,如果 window 的長度為偶數時就會是在 window/2 + 1 個位置上。

import pandas as pd
import matplotlib.pyplot as plt

stock1 = pd.read_excel(’sz50.xlsx',sheet_name = '600036.XSHG', index_col = 'datetime')
part = stock1.close.head(10)
print(part.rolling(window = 4).sum())

expanding()

         expanding 和 rolling 本質是相同的,只不過 expanding 可以忽略 nan 而 rolling 不行,從下面的例子可以看出來。

import pandas as pd
import numpy as np

sn = pd.Series([1, 2, np.nan, 3, np.nan, 4])
print(sn.rolling(window = 2).sum())
print(sn.expanding(2).sum())

apply() & aggregate()

         apply 方法在剛才我們談到的 rolling 的方法中有出現,但是並不侷限與 rolling 得到的物件,DataFrame、Series 乃至大多數物件都有 apply 方法,可以供我們執行自己建立的函式。這個函式要求是要以一個 ndarray 作為輸入然後輸出單個值。

        以 rolling 得到的 Rolling 物件舉例。我們定義了一個函式 mad,這個函式計算的是一個日期對應的視窗中的所有值,各自與他們均值的差的絕對值(np.fabs 計算絕對值)的平均值。我們也可以寫成一個公式,假設 window = 5:

\sum_{i = t - 4}^{t}\left |x(i) - \sum_{i = t - 4}^{t}x(i)/5 \right |/5

那這個計算式有什麼意義呢??與均值的差的絕對值的均值在定義上類似於方差,都是描述波動的強度,我們把這種方式描述的震盪強度和走勢一起繪製,注意二者的大小不同。而且 pandas 中的物件都支援 plot 方法,得到的是一個 AxisSubplots 物件,直接 plt.show 就可以得到,更加方便了。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

stock1 = pd.read_excel("sz50.xlsx", sheet_name = '601318.XSHG', index_col = 'datetime')
close = stock1.close
rol = close.rolling(5)
mad = lambda x:np.fabs(x - x.mean()).mean()
ax = rol.apply(mad).plot()
ax1 = ax.twinx()
ax1.plot(close, c= 'r')
plt.show()

          可以看到,藍色代表震盪,紅色代表走勢,在有較大漲幅時波動性也會更強。不過,波動性終究是個滯後指標,無法幫助我們進行更多有價值的預測。

          DataFrame 和 Series 應用 apply 方法類似,不過前者有引數 axis 來控制是將行(1)或者列(0)看成在函式中會用到的array。