目錄
- 簡介
- 滾動視窗
- Center window
- Weighted window 權重視窗
- 擴充視窗
- 指數權重視窗
在資料統計中,經常需要進行一些範圍操作,這些範圍我們可以稱之為一個window 。Pandas提供了一個rolling方法,通過滾動window來進行統計計算。
本文将會探讨一下rolling中的window用法。
我們有5個數,我們希望滾動統計兩個數的和,那麼可以這樣:
In [1]: s = pd.Series(range(5))
In [2]: s.rolling(window=2).sum()
Out[2]:
0 NaN
1 1.0
2 3.0
3 5.0
4 7.0
dtype: float64
rolling 對象可以通過for來周遊:
In [3]: for window in s.rolling(window=2):
...: print(window)
...:
0 0
dtype: int64
0 0
1 1
dtype: int64
1 1
2 2
dtype: int64
2 2
3 3
dtype: int64
3 3
4 4
dtype: int64
pandas中有四種window操作,我們看下他們的定義:
名稱 | 方法 | 傳回對象 | 是否支援時間序列 | 是否支援鍊式groupby操作 |
---|---|---|---|---|
固定或者可滑動的視窗 | | | Yes | |
scipy.signal庫提供的權重非矩形視窗 | | | No | |
累積值的視窗 | | | ||
值上的累積和指數權重視窗 | | | Yes (as of version 1.2) |
看一個基于時間rolling的例子:
In [4]: s = pd.Series(range(5), index=pd.date_range('2020-01-01', periods=5, freq='1D'))
In [5]: s.rolling(window='2D').sum()
Out[5]:
2020-01-01 0.0
2020-01-02 1.0
2020-01-03 3.0
2020-01-04 5.0
2020-01-05 7.0
Freq: D, dtype: float64
設定min_periods可以指定window中的最小的NaN的個數:
In [8]: s = pd.Series([np.nan, 1, 2, np.nan, np.nan, 3])
In [9]: s.rolling(window=3, min_periods=1).sum()
Out[9]:
0 NaN
1 1.0
2 3.0
3 3.0
4 2.0
5 3.0
dtype: float64
In [10]: s.rolling(window=3, min_periods=2).sum()
Out[10]:
0 NaN
1 NaN
2 3.0
3 3.0
4 NaN
5 NaN
dtype: float64
# Equivalent to min_periods=3
In [11]: s.rolling(window=3, min_periods=None).sum()
Out[11]:
0 NaN
1 NaN
2 NaN
3 NaN
4 NaN
5 NaN
dtype: float64
預設情況下window的統計是以最右為準,比如window=5,那麼前面的0,1,2,3 因為沒有達到5,是以為NaN。
In [19]: s = pd.Series(range(10))
In [20]: s.rolling(window=5).mean()
Out[20]:
0 NaN
1 NaN
2 NaN
3 NaN
4 2.0
5 3.0
6 4.0
7 5.0
8 6.0
9 7.0
dtype: float64
可以對這種方式進行修改,設定 center=True 可以從中間統計:
In [21]: s.rolling(window=5, center=True).mean()
Out[21]:
0 NaN
1 NaN
2 2.0
3 3.0
4 4.0
5 5.0
6 6.0
7 7.0
8 NaN
9 NaN
dtype: float64
使用 win_type 可以指定權重視窗的類型。其中win_type 必須是scipy.signal 中的window類型。
舉幾個例子:
In [47]: s = pd.Series(range(10))
In [48]: s.rolling(window=5).mean()
Out[48]:
0 NaN
1 NaN
2 NaN
3 NaN
4 2.0
5 3.0
6 4.0
7 5.0
8 6.0
9 7.0
dtype: float64
In [49]: s.rolling(window=5, win_type="triang").mean()
Out[49]:
0 NaN
1 NaN
2 NaN
3 NaN
4 2.0
5 3.0
6 4.0
7 5.0
8 6.0
9 7.0
dtype: float64
# Supplementary Scipy arguments passed in the aggregation function
In [50]: s.rolling(window=5, win_type="gaussian").mean(std=0.1)
Out[50]:
0 NaN
1 NaN
2 NaN
3 NaN
4 2.0
5 3.0
6 4.0
7 5.0
8 6.0
9 7.0
dtype: float64
擴充視窗會産生聚合統計資訊的值,其中包含該時間點之前的所有可用資料。
In [51]: df = pd.DataFrame(range(5))
In [52]: df.rolling(window=len(df), min_periods=1).mean()
Out[52]:
0
0 0.0
1 0.5
2 1.0
3 1.5
4 2.0
In [53]: df.expanding(min_periods=1).mean()
Out[53]:
0
0 0.0
1 0.5
2 1.0
3 1.5
4 2.0
指數權重視窗與擴充視窗相似,但每個先驗點相對于目前點均按指數權重。
權重計算的公式是這樣的:
\(y_t=Σ^t_{i=0}{w_ix_{t-i}\over{Σ^t_{i=0}w_i}}\)
其中\(x_t\)是輸入,\(y_t\)是輸出,\(w_i\)是權重。
EW有兩種模式,一種模式是
adjust=True
,這種情況下 \(𝑤_𝑖=(1−𝛼)^𝑖\)
一種模式是
adjust=False
,這種情況下:
\[y_0=x_0\\n
y_t=(1-a)y_{t-1}+ax_t
\]
其中 0<𝛼≤1, 根據EM方式的不同a可以有不同的取值:
\[a=\{ {{2\over {s+1}} \qquad span模式 其中s >= 1\\ {1\over{1+c}}\qquad center of mass c>=0 \\ 1-exp^{log0.5\over h} \qquad half-life h > 0 }
舉個例子:
In [54]: df = pd.DataFrame({"B": [0, 1, 2, np.nan, 4]})
In [55]: df
Out[55]:
B
0 0.0
1 1.0
2 2.0
3 NaN
4 4.0
In [56]: times = ["2020-01-01", "2020-01-03", "2020-01-10", "2020-01-15", "2020-01-17"]
In [57]: df.ewm(halflife="4 days", times=pd.DatetimeIndex(times)).mean()
Out[57]:
B
0 0.000000
1 0.585786
2 1.523889
3 1.523889
4 3.233686
本文已收錄于 http://www.flydean.com/12-python-pandas-window/
最通俗的解讀,最深刻的幹貨,最簡潔的教程,衆多你不知道的小技巧等你來發現!