窗口操作#
pandas 包含一组紧凑的 API,用于执行窗口操作——一种对值的滑动分区执行聚合的操作。此 API 的功能类似于 groupby
API,Series
和 DataFrame
调用窗口方法并传入必要的参数,然后后续调用聚合函数。
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
窗口是通过从当前观测值回溯窗口长度来组成的。上面的结果可以通过对以下数据的窗口分区求和来得出
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 支持 4 种类型的窗口操作
滚动窗口:对值进行通用的固定或可变滑动窗口操作。
加权窗口:由
scipy.signal
库提供的加权非矩形窗口。扩展窗口:对值进行累积窗口操作。
指数加权窗口:对值进行累积和指数加权窗口操作。
概念 |
方法 |
返回对象 |
支持基于时间的窗口 |
支持链式 groupby |
支持 table 方法 |
支持在线操作 |
---|---|---|---|---|---|---|
滚动窗口 |
|
|
是 |
是 |
是 (版本 1.3 起) |
否 |
加权窗口 |
|
|
否 |
否 |
否 |
否 |
扩展窗口 |
|
|
否 |
是 |
是 (版本 1.3 起) |
否 |
指数加权窗口 |
|
|
否 |
是 (版本 1.2 起) |
否 |
是 (版本 1.3 起) |
如上所述,某些操作支持基于时间偏移量指定窗口
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
此外,某些方法支持将 groupby
操作与窗口操作链式调用,这将首先按指定的键对数据进行分组,然后对每个组执行窗口操作。
In [6]: df = pd.DataFrame({'A': ['a', 'b', 'a', 'b', 'a'], 'B': range(5)})
In [7]: df.groupby('A').expanding().sum()
Out[7]:
B
A
a 0 0.0
2 2.0
4 6.0
b 1 1.0
3 4.0
注意
窗口操作目前仅支持数值数据(整数和浮点数),并将始终返回 float64
值。
警告
由于底层窗口算法累积求和,某些窗口聚合方法(如 mean
、sum
、var
和 std
)可能会出现数值不精确。当值的幅度差达到 \(1/np.finfo(np.double).eps\) 时,会导致截断。必须注意,大数值可能会影响不包含这些数值的窗口。Kahan 求和算法 被用于计算滚动和,以尽可能保持精度。
始于版本 1.3.0。
某些窗口操作还支持构造函数中的 method='table'
选项,该选项对整个 DataFrame
执行窗口操作,而不是一次只处理一列或一行。对于具有许多列或行(并带有相应的 axis
参数)的 DataFrame
,这可以提供有益的性能提升,或者能够在窗口操作期间利用其他列。method='table'
选项仅在相应方法调用中指定了 engine='numba'
时才能使用。
例如,可以通过指定单独的权重列,使用 apply()
计算加权平均值。
In [8]: def weighted_mean(x):
...: arr = np.ones((1, x.shape[1]))
...: arr[:, :2] = (x[:, :2] * x[:, 2]).sum(axis=0) / x[:, 2].sum()
...: return arr
...:
In [9]: df = pd.DataFrame([[1, 2, 0.6], [2, 3, 0.4], [3, 4, 0.2], [4, 5, 0.7]])
In [10]: df.rolling(2, method="table", min_periods=0).apply(weighted_mean, raw=True, engine="numba") # noqa: E501
Out[10]:
0 1 2
0 1.000000 2.000000 1.0
1 1.800000 2.000000 1.0
2 3.333333 2.333333 1.0
3 1.555556 7.000000 1.0
始于版本 1.3。
某些窗口操作在构造窗口对象后还支持一个 online
方法,该方法返回一个新对象,支持传入新的 DataFrame
或 Series
对象,以继续使用新值进行窗口计算(即在线计算)。
这个新窗口对象上的方法必须首先调用聚合方法来“初始化”在线计算的初始状态。然后,可以将新的 DataFrame
或 Series
对象通过 update
参数传入,以继续进行窗口计算。
In [11]: df = pd.DataFrame([[1, 2, 0.6], [2, 3, 0.4], [3, 4, 0.2], [4, 5, 0.7]])
In [12]: df.ewm(0.5).mean()
Out[12]:
0 1 2
0 1.000000 2.000000 0.600000
1 1.750000 2.750000 0.450000
2 2.615385 3.615385 0.276923
3 3.550000 4.550000 0.562500
In [13]: online_ewm = df.head(2).ewm(0.5).online()
In [14]: online_ewm.mean()
Out[14]:
0 1 2
0 1.00 2.00 0.60
1 1.75 2.75 0.45
In [15]: online_ewm.mean(update=df.tail(1))
Out[15]:
0 1 2
3 3.307692 4.307692 0.623077
所有窗口操作都支持 min_periods
参数,该参数指定一个窗口必须包含的非 np.nan
值的最小数量;否则,结果值为 np.nan
。min_periods
对于基于时间的窗口默认为 1,对于固定窗口默认为 window
。
In [16]: s = pd.Series([np.nan, 1, 2, np.nan, np.nan, 3])
In [17]: s.rolling(window=3, min_periods=1).sum()
Out[17]:
0 NaN
1 1.0
2 3.0
3 3.0
4 2.0
5 3.0
dtype: float64
In [18]: s.rolling(window=3, min_periods=2).sum()
Out[18]:
0 NaN
1 NaN
2 3.0
3 3.0
4 NaN
5 NaN
dtype: float64
# Equivalent to min_periods=3
In [19]: s.rolling(window=3, min_periods=None).sum()
Out[19]:
0 NaN
1 NaN
2 NaN
3 NaN
4 NaN
5 NaN
dtype: float64
此外,所有窗口操作都支持 aggregate
方法,用于返回应用于单个窗口的多个聚合的结果。
In [20]: df = pd.DataFrame({"A": range(5), "B": range(10, 15)})
In [21]: df.expanding().agg(["sum", "mean", "std"])
Out[21]:
A B
sum mean std sum mean std
0 0.0 0.0 NaN 10.0 10.0 NaN
1 1.0 0.5 0.707107 21.0 10.5 0.707107
2 3.0 1.0 1.000000 33.0 11.0 1.000000
3 6.0 1.5 1.290994 46.0 11.5 1.290994
4 10.0 2.0 1.581139 60.0 12.0 1.581139
滚动窗口#
通用滚动窗口支持将窗口指定为固定数量的观测值或基于偏移量的可变数量观测值。如果提供基于时间的偏移量,则相应的基于时间的索引必须是单调的。
In [22]: times = ['2020-01-01', '2020-01-03', '2020-01-04', '2020-01-05', '2020-01-29']
In [23]: s = pd.Series(range(5), index=pd.DatetimeIndex(times))
In [24]: s
Out[24]:
2020-01-01 0
2020-01-03 1
2020-01-04 2
2020-01-05 3
2020-01-29 4
dtype: int64
# Window with 2 observations
In [25]: s.rolling(window=2).sum()
Out[25]:
2020-01-01 NaN
2020-01-03 1.0
2020-01-04 3.0
2020-01-05 5.0
2020-01-29 7.0
dtype: float64
# Window with 2 days worth of observations
In [26]: s.rolling(window='2D').sum()
Out[26]:
2020-01-01 0.0
2020-01-03 1.0
2020-01-04 3.0
2020-01-05 5.0
2020-01-29 4.0
dtype: float64
有关所有支持的聚合函数,请参见滚动窗口函数。
窗口居中#
默认情况下,标签位于窗口的右边缘,但可以使用 center
关键字将标签设置在中心。
In [27]: s = pd.Series(range(10))
In [28]: s.rolling(window=5).mean()
Out[28]:
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 [29]: s.rolling(window=5, center=True).mean()
Out[29]:
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
这也可以应用于日期时间类索引。
始于版本 1.3.0。
In [30]: df = pd.DataFrame(
....: {"A": [0, 1, 2, 3, 4]}, index=pd.date_range("2020", periods=5, freq="1D")
....: )
....:
In [31]: df
Out[31]:
A
2020-01-01 0
2020-01-02 1
2020-01-03 2
2020-01-04 3
2020-01-05 4
In [32]: df.rolling("2D", center=False).mean()
Out[32]:
A
2020-01-01 0.0
2020-01-02 0.5
2020-01-03 1.5
2020-01-04 2.5
2020-01-05 3.5
In [33]: df.rolling("2D", center=True).mean()
Out[33]:
A
2020-01-01 0.5
2020-01-02 1.5
2020-01-03 2.5
2020-01-04 3.5
2020-01-05 4.0
滚动窗口端点#
滚动窗口计算中是否包含区间端点可以通过 closed
参数指定
值 |
行为 |
---|---|
|
闭合右端点 |
|
闭合左端点 |
|
闭合左右端点 |
|
开放端点 |
例如,在许多需要避免当前信息污染过去信息的问题中,右端点开放很有用。这使得滚动窗口能够计算“截至该时间点”(但不包括该时间点)的统计数据。
In [34]: df = pd.DataFrame(
....: {"x": 1},
....: index=[
....: pd.Timestamp("20130101 09:00:01"),
....: pd.Timestamp("20130101 09:00:02"),
....: pd.Timestamp("20130101 09:00:03"),
....: pd.Timestamp("20130101 09:00:04"),
....: pd.Timestamp("20130101 09:00:06"),
....: ],
....: )
....:
In [35]: df["right"] = df.rolling("2s", closed="right").x.sum() # default
In [36]: df["both"] = df.rolling("2s", closed="both").x.sum()
In [37]: df["left"] = df.rolling("2s", closed="left").x.sum()
In [38]: df["neither"] = df.rolling("2s", closed="neither").x.sum()
In [39]: df
Out[39]:
x right both left neither
2013-01-01 09:00:01 1 1.0 1.0 NaN NaN
2013-01-01 09:00:02 1 2.0 2.0 1.0 1.0
2013-01-01 09:00:03 1 2.0 3.0 2.0 1.0
2013-01-01 09:00:04 1 2.0 3.0 2.0 1.0
2013-01-01 09:00:06 1 1.0 2.0 1.0 NaN
自定义窗口滚动#
除了接受整数或偏移量作为 window
参数外,rolling
还接受一个 BaseIndexer
子类,允许用户定义计算窗口边界的自定义方法。BaseIndexer
子类需要定义一个 get_window_bounds
方法,该方法返回一个包含两个数组的元组,第一个数组是窗口的起始索引,第二个数组是窗口的结束索引。此外,num_values
、min_periods
、center
、closed
和 step
将自动传递给 get_window_bounds
,并且定义的方法必须始终接受这些参数。
例如,如果我们有以下 DataFrame
In [40]: use_expanding = [True, False, True, False, True]
In [41]: use_expanding
Out[41]: [True, False, True, False, True]
In [42]: df = pd.DataFrame({"values": range(5)})
In [43]: df
Out[43]:
values
0 0
1 1
2 2
3 3
4 4
并且我们想要使用一个扩展窗口(当 use_expanding
为 True
时)或者一个大小为 1 的窗口(否则),我们可以创建以下 BaseIndexer
子类
In [44]: from pandas.api.indexers import BaseIndexer
In [45]: class CustomIndexer(BaseIndexer):
....: def get_window_bounds(self, num_values, min_periods, center, closed, step):
....: start = np.empty(num_values, dtype=np.int64)
....: end = np.empty(num_values, dtype=np.int64)
....: for i in range(num_values):
....: if self.use_expanding[i]:
....: start[i] = 0
....: end[i] = i + 1
....: else:
....: start[i] = i
....: end[i] = i + self.window_size
....: return start, end
....:
In [46]: indexer = CustomIndexer(window_size=1, use_expanding=use_expanding)
In [47]: df.rolling(indexer).sum()
Out[47]:
values
0 0.0
1 1.0
2 3.0
3 3.0
4 10.0
您可以在此处查看 BaseIndexer
子类的其他示例
在这些示例中,值得注意的一个子类是 VariableOffsetWindowIndexer
,它允许对非固定偏移量(例如 BusinessDay
)执行滚动操作。
In [48]: from pandas.api.indexers import VariableOffsetWindowIndexer
In [49]: df = pd.DataFrame(range(10), index=pd.date_range("2020", periods=10))
In [50]: offset = pd.offsets.BDay(1)
In [51]: indexer = VariableOffsetWindowIndexer(index=df.index, offset=offset)
In [52]: df
Out[52]:
0
2020-01-01 0
2020-01-02 1
2020-01-03 2
2020-01-04 3
2020-01-05 4
2020-01-06 5
2020-01-07 6
2020-01-08 7
2020-01-09 8
2020-01-10 9
In [53]: df.rolling(indexer).sum()
Out[53]:
0
2020-01-01 0.0
2020-01-02 1.0
2020-01-03 2.0
2020-01-04 3.0
2020-01-05 7.0
2020-01-06 12.0
2020-01-07 6.0
2020-01-08 7.0
2020-01-09 8.0
2020-01-10 9.0
对于某些问题,可以利用未来的信息进行分析。例如,当每个数据点都是从实验中读取的完整时间序列,并且任务是提取潜在条件时,就会出现这种情况。在这种情况下,执行前向滚动窗口计算会很有用。FixedForwardWindowIndexer
类可用于此目的。这个 BaseIndexer
子类实现了一个闭合的固定宽度前向滚动窗口,我们可以按如下方式使用它
In [54]: from pandas.api.indexers import FixedForwardWindowIndexer
In [55]: indexer = FixedForwardWindowIndexer(window_size=2)
In [56]: df.rolling(indexer, min_periods=1).sum()
Out[56]:
0
2020-01-01 1.0
2020-01-02 3.0
2020-01-03 5.0
2020-01-04 7.0
2020-01-05 9.0
2020-01-06 11.0
2020-01-07 13.0
2020-01-08 15.0
2020-01-09 17.0
2020-01-10 9.0
我们还可以通过切片、应用滚动聚合,然后翻转结果来实现这一点,如下例所示
In [57]: df = pd.DataFrame(
....: data=[
....: [pd.Timestamp("2018-01-01 00:00:00"), 100],
....: [pd.Timestamp("2018-01-01 00:00:01"), 101],
....: [pd.Timestamp("2018-01-01 00:00:03"), 103],
....: [pd.Timestamp("2018-01-01 00:00:04"), 111],
....: ],
....: columns=["time", "value"],
....: ).set_index("time")
....:
In [58]: df
Out[58]:
value
time
2018-01-01 00:00:00 100
2018-01-01 00:00:01 101
2018-01-01 00:00:03 103
2018-01-01 00:00:04 111
In [59]: reversed_df = df[::-1].rolling("2s").sum()[::-1]
In [60]: reversed_df
Out[60]:
value
time
2018-01-01 00:00:00 201.0
2018-01-01 00:00:01 101.0
2018-01-01 00:00:03 214.0
2018-01-01 00:00:04 111.0
滚动 apply#
apply()
函数接受一个额外的 func
参数,并执行通用的滚动计算。func
参数应该是一个函数,该函数从 ndarray 输入产生单个值。raw
参数指定窗口是强制转换为 Series
对象(raw=False
)还是 ndarray 对象(raw=True
)。
In [61]: def mad(x):
....: return np.fabs(x - x.mean()).mean()
....:
In [62]: s = pd.Series(range(10))
In [63]: s.rolling(window=4).apply(mad, raw=True)
Out[63]:
0 NaN
1 NaN
2 NaN
3 1.0
4 1.0
5 1.0
6 1.0
7 1.0
8 1.0
9 1.0
dtype: float64
Numba 引擎#
此外,如果安装了可选依赖项 Numba,apply()
可以利用它。通过指定 engine='numba'
和 engine_kwargs
参数(raw
也必须设置为 True
),可以使用 Numba 执行 apply 聚合。有关参数的一般用法和性能考虑事项,请参见使用 Numba 提升性能。
Numba 可能会应用于两个例程中
如果
func
是标准的 Python 函数,引擎将对传入的函数进行 JIT 编译。func
也可以是已经 JIT 编译过的函数,在这种情况下,引擎不会再次对其进行 JIT 编译。引擎将对 apply 函数应用于每个窗口的 for 循环进行 JIT 编译。
engine_kwargs
参数是一个关键字参数字典,将传递给 numba.jit 装饰器。这些关键字参数将应用于传入的函数(如果是标准 Python 函数)和应用于每个窗口的 apply for 循环。
始于版本 1.3.0。
mean
、median
、max
、min
和 sum
也支持 engine
和 engine_kwargs
参数。
二元窗口函数#
cov()
和 corr()
可以计算两个 Series
或任意组合的 DataFrame
/Series
或 DataFrame
/DataFrame
的滑动窗口统计数据。以下是每种情况的行为:
两个
Series
:计算配对的统计数据。DataFrame
/Series
:计算 DataFrame 中每列与传入 Series 的统计数据,因此返回一个 DataFrame。DataFrame
/DataFrame
:默认计算匹配列名的统计数据,返回一个 DataFrame。如果传递关键字参数pairwise=True
,则计算每对列的统计数据,返回一个具有MultiIndex
的DataFrame
,其值是相关日期(参见下一节)。
例如
In [64]: df = pd.DataFrame(
....: np.random.randn(10, 4),
....: index=pd.date_range("2020-01-01", periods=10),
....: columns=["A", "B", "C", "D"],
....: )
....:
In [65]: df = df.cumsum()
In [66]: df2 = df[:4]
In [67]: df2.rolling(window=2).corr(df2["B"])
Out[67]:
A B C D
2020-01-01 NaN NaN NaN NaN
2020-01-02 -1.0 1.0 -1.0 1.0
2020-01-03 1.0 1.0 1.0 -1.0
2020-01-04 -1.0 1.0 1.0 -1.0
计算滚动的成对协方差和相关系数#
在金融数据分析和其他领域,计算一系列时间序列的协方差和相关系数矩阵是很常见的。通常人们也对滑动窗口的协方差和相关系数矩阵感兴趣。这可以通过传递 pairwise
关键字参数来完成,对于 DataFrame
输入,这将产生一个具有 MultiIndex 的 DataFrame
,其 index
是相关日期。对于单个 DataFrame 参数,甚至可以省略 pairwise
参数
注意
缺失值被忽略,并且每个条目都使用成对完整的观测值计算。
假设缺失数据是随机缺失的,这将产生一个无偏的协方差矩阵估计。然而,对于许多应用来说,这个估计可能不可接受,因为估计的协方差矩阵不保证是半正定的。这可能导致估计的相关系数绝对值大于一,和/或非可逆的协方差矩阵。有关更多详细信息,请参见 Wikipedia 上的协方差矩阵估计。
In [68]: covs = (
....: df[["B", "C", "D"]]
....: .rolling(window=4)
....: .cov(df[["A", "B", "C"]], pairwise=True)
....: )
....:
In [69]: covs
Out[69]:
B C D
2020-01-01 A NaN NaN NaN
B NaN NaN NaN
C NaN NaN NaN
2020-01-02 A NaN NaN NaN
B NaN NaN NaN
... ... ... ...
2020-01-09 B 0.342006 0.230190 0.052849
C 0.230190 1.575251 0.082901
2020-01-10 A -0.333945 0.006871 -0.655514
B 0.649711 0.430860 0.469271
C 0.430860 0.829721 0.055300
[30 rows x 3 columns]
加权窗口#
.rolling
中的 win_type
参数生成加权窗口,这些窗口常用于滤波和频谱估计。win_type
必须是与 scipy.signal 窗口函数对应的字符串。必须安装 Scipy 才能使用这些窗口,并且 Scipy 窗口方法接受的补充参数必须在聚合函数中指定。
In [70]: s = pd.Series(range(10))
In [71]: s.rolling(window=5).mean()
Out[71]:
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 [72]: s.rolling(window=5, win_type="triang").mean()
Out[72]:
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 [73]: s.rolling(window=5, win_type="gaussian").mean(std=0.1)
Out[73]:
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
有关所有支持的聚合函数,请参见加权窗口函数。
扩展窗口#
扩展窗口返回截至该时间点可用所有数据的聚合统计值。由于这些计算是滚动统计的特例,它们在 pandas 中的实现使得以下两个调用是等效的
In [74]: df = pd.DataFrame(range(5))
In [75]: df.rolling(window=len(df), min_periods=1).mean()
Out[75]:
0
0 0.0
1 0.5
2 1.0
3 1.5
4 2.0
In [76]: df.expanding(min_periods=1).mean()
Out[76]:
0
0 0.0
1 0.5
2 1.0
3 1.5
4 2.0
有关所有支持的聚合函数,请参见扩展窗口函数。
指数加权窗口#
指数加权窗口类似于扩展窗口,但每个先前的数据点相对于当前点被指数级地加权减小。
通常,加权移动平均值计算如下
其中 \(x_t\) 是输入,\(y_t\) 是结果,\(w_i\) 是权重。
有关所有支持的聚合函数,请参见指数加权窗口函数。
EW 函数支持两种指数权重的变体。默认情况下,adjust=True
使用权重 \(w_i = (1 - \alpha)^i\),得到
当指定 adjust=False
时,移动平均值计算如下
这等效于使用权重
注意
这些方程有时也用 \(\alpha' = 1 - \alpha\) 表示,例如
上述两种变体之间的差异在于我们处理的是有限历史的序列。考虑一个无限历史的序列,使用 adjust=True
注意到分母是一个首项为 1、公比为 \(1 - \alpha\) 的几何级数,我们得到
这与上述 adjust=False
的表达式相同,因此说明了对于无限序列,这两种变体是等效的。当 adjust=False
时,我们有 \(y_0 = x_0\) 且 \(y_t = \alpha x_t + (1 - \alpha) y_{t-1}\)。因此,这里假设 \(x_0\) 不是一个普通值,而是截至该点无限序列的指数加权矩。
必须满足 \(0 < \alpha \leq 1\),虽然可以直接传递 \(\alpha\),但通常更容易考虑 EW 矩的**跨度 (span)**、**质心 (com)** 或**半衰期 (half-life)**
对于 EW 函数,必须精确指定**跨度 (span)**、**质心 (center of mass)**、**半衰期 (half-life)** 和 **alpha** 中的一个参数
**跨度 (Span)** 对应于通常所说的“N 天 EW 移动平均”。
**质心 (Center of mass)** 具有更物理的解释,可以从跨度来看待:\(c = (s - 1) / 2\)。
**半衰期 (Half-life)** 是指数权重减小到一半所需的时间段。
**Alpha** 直接指定平滑因子。
您还可以使用可转换为 timedelta 的单位来指定 halflife
,以指示在同时指定 times
序列时观测值衰减到其值一半所需的时间量。
In [77]: df = pd.DataFrame({"B": [0, 1, 2, np.nan, 4]})
In [78]: df
Out[78]:
B
0 0.0
1 1.0
2 2.0
3 NaN
4 4.0
In [79]: times = ["2020-01-01", "2020-01-03", "2020-01-10", "2020-01-15", "2020-01-17"]
In [80]: df.ewm(halflife="4 days", times=pd.DatetimeIndex(times)).mean()
Out[80]:
B
0 0.000000
1 0.585786
2 1.523889
3 1.523889
4 3.233686
使用以下公式计算带有时间输入向量的指数加权平均值
ExponentialMovingWindow 还有一个 ignore_na
参数,它决定了中间的空值如何影响权重的计算。当 ignore_na=False
(默认)时,权重是基于绝对位置计算的,因此中间的空值会影响结果。当 ignore_na=True
时,计算权重时会忽略中间的空值。例如,假设 adjust=True
,如果 ignore_na=False
,3, NaN, 5
的加权平均值计算如下
而如果 ignore_na=True
,加权平均值计算如下
var()
、std()
和 cov()
函数有一个 bias
参数,用于指定结果是否包含有偏或无偏统计量。例如,如果 bias=True
,ewmvar(x)
计算为 ewmvar(x) = ewma(x**2) - ewma(x)**2
;而如果 bias=False
(默认),则有偏方差统计量会乘以以下去偏因子进行缩放
(对于 \(w_i = 1\),这会简化为通常的 \(N / (N - 1)\) 因子,其中 \(N = t + 1\)。) 有关更多详细信息,请参阅维基百科上的加权样本方差。