Pandas 中文参考指南
Windowing operations
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
Overview
pandas 支持 4 种窗口化操作类型:
-
滚动窗口:针对值进行的通用固定或可变滑动窗口。
-
加权窗口:scipy.signal 库提供的加权非矩形窗口。
-
扩展窗口:针对值进行累计窗口。
-
指数加权窗口:针对值进行累计和指数加权窗口。
概念
方法
返回的对象
支持基于时间的窗口
支持链式 groupby
支持表方法
支持在线操作
滚动窗口
rolling
pandas.typing.api.Rolling
是
是
是(从版本 1.3 开始)
否
加权窗口
rolling
pandas.typing.api.Window
否
否
否
否
扩展窗口
expanding
pandas.typing.api.Expanding
否
是
是(从版本 1.3 开始)
否
指数加权窗口
ewm
pandas.typing.api.ExponentialMovingWindow
否
是(版本 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 summation 用于计算滚动和,以尽可能保持准确性。
1.3.0 版中的新增功能。
某些窗口化操作还支持构造函数中的 method='table' 选项,该选项对整个 DataFrame 执行窗口化操作,而不是一次针对单列或单行执行。对于具有许多列或行的 DataFrame (具有相应的 axis 参数),或者在窗口化操作过程中利用其他列的能力,这可以提供有用的性能优势。只有在相应的函数调用中指定了 engine='numba' 时才能使用 method='table' 选项。
例如, weighted mean 计算可以通过 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 版新增功能。
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_默认为 1。
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
Rolling window
通用滚动窗口支持指定窗口为固定数量的观测值或基于偏移量的可变数量的观测值。如果提供了基于时间的偏移量,则基于时间的相应索引必须是单调的。
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
有关所有受支持的聚合函数,请参见 Rolling window functions。
Centering windows
默认情况下,标签被设置为窗口的右边缘,但_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
Rolling window endpoints
可以使用_closed_参数指定滚动窗口计算中包含区间端点:
值
行为
'right'
关闭右端点
'left'
关闭左端点
'both'
关闭两个端点
'neither'
打开端点
例如,在很多问题中,如果来自现在的信息不会影响过去的信息,则打开右端点非常有用。这允许滚动窗口计算“直到时间点”的统计信息,但不包括该时间点。
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
Custom window rolling
除了接受整数或偏移量作为_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
你可以在 here 中查看 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
Rolling 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 engine
此外,如果已安装 apply() 作为可选依赖项,它可以使用 Numba。可以通过指定 engine='numba' 和 engine_kwargs 参数使用 Numba 执行应用聚合(raw 也必须设置为 True)。有关参数和性能注意事项的一般用法,请参阅 enhancing performance with Numba。
Numba 将在两个例程中应用:
-
如果 func 是一个标准 Python 函数,引擎将 JIT 传递的函数。func 也可以是一个 JITed 函数,在这种情况下,引擎不会再次 JIT 化函数。
-
引擎将 JIT 化应用函数应用到每个窗口的 for 循环。
engine_kwargs 参数是传入 numba.jit decorator 的关键字参数的字典。这些关键字参数将应用到传递的函数(如果是一个标准 Python 函数)和循环中每个窗口的 apply。
1.3.0 版中的新增功能。
mean、median、max、min 和 sum 也支持 engine 和 engine_kwargs 参数。
Binary window functions
cov() 和 corr() 可以计算有关两个 Series 或 DataFrame/ Series 或 DataFrame/ DataFrame 的任何组合的移动窗口统计信息。以下是每种情况中的行为:
-
两个 Series:计算配对的统计信息。
-
DataFrame/ Series:计算 DataFrame 的每一列的统计信息,并传入 Series,从而返回一个 DataFrame。
-
DataFrame/ DataFrame:默认情况下,计算匹配列名的统计信息,并返回一个 DataFrame。如果传递了关键字参数 pairwise=True,则计算每一对列的统计信息,并返回一个 DataFrame,其 MultiIndex 的值是相关日期(请参阅 the next section)。
例如:
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
Computing rolling pairwise covariances and correlations
在金融数据分析和其他领域中,通常为一系列时间序列计算协方差和相关矩阵。人们通常还对移动窗口协方差和相关矩阵感兴趣。这可以通过传递 pairwise 关键字参数来完成,在 DataFrame 输入的情况下,它将产生一个 MultiIndexed DataFrame,其 index 是相关日期。在单个 DataFrame 参数的情况下,甚至可以省略 pairwise 参数:
将忽略缺失值,并且每个条目都是使用成对的完整观测来计算的。 |
假设缺失数据是随机缺失的,这样就会产生一个协方差矩阵的估计值,该估计值是无偏的。但是,对于许多应用程序,此估计值可能不可接受,因为估计的协方差矩阵不能保证为正半定的。这可能导致估计的相关值有大于 1 的绝对值和/或不可逆的协方差矩阵。有关更多详细信息,请参阅 Estimation of covariance matrices。
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]
Weighted window
win_type 参数在 .rolling 中生成加权窗口,通常用于滤波和频谱估计。win_type 必须是与 scipy.signal window function 对应的字符串。为了使用这些窗口,必须安装 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
有关所有受支持的聚合函数,请参阅 Weighted window functions。
Expanding window
扩展窗口通过到目前为止所有可用数据计算聚合统计值。由于这些计算是滚动统计的特殊情况,因此它们实现在 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
有关所有受支持的聚合函数,请参阅 Expanding window functions。
Exponentially weighted window
指数加权窗口类似于扩展窗口,但是相对于当前点,每个先验点都以指数加权向下。
通常,加权移动平均数的计算方式如下:
其中 \(x_t\) 是输入,\(y_t\) 是结果和 \(w_i\) 是权重。
有关所有受支持的聚合函数,请参阅 Exponentially-weighted window functions。
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 矩的跨度、质心 (com) 或半衰期:
必须明确地将跨度、质心、半衰期和 alpha 中的一个指定给 EW 函数:
-
跨度对应于通常所说的“N 日 EW 移动平均值”。
-
质心具有更物理的解释,可以用跨度来考虑:\(c = (s - 1) / 2\).
-
半衰期是指数权重减少到一半所需的时间段。
-
Alpha 直接指定平滑因子。
你还可以使用 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\)。)有关详细信息,请参见维基百科上的 Weighted Sample Variance。