是否有一种快速(准确)的方法来计算数据集的样本方差,直到第 n 个元素?
Is there a fast (and accurate) way to calculate the sample variance of a data-set till the n-th element?
我需要计算数据集的样本方差直到第 n 个元素,例如
x = np.random.randint(1, 7, 10)
--> [5 2 2 5 3 5 2 5 4 2]
快速简便的方法是使用 np.var(x) 或 Welfords 算法的实现,但它们只计算整个数据集的方差。
对于我的应用程序,我需要一个数组中的方差元素,以便在第 n 个元素中它将是与数据集中第一个第 n 个数据点的方差。
例如:
x_var[2]
--> variance of [5 2 2]
--> 1.7320508
x_var[9]
--> variance of [5 2 2 5 3 5 2 5 4 2]
--> 2.0555556
我的解决方案是将数组分割成 n 个数组,这样我就可以在每个数组上使用 np.var 来获得 运行 方差。这有效,但速度非常慢。
for i in range(0,n):
x_var[i] = np.var(x[:i])
我已经快速实现了 运行 均值,所以我有一个数组,其中的均值一直到第 n 个条目中的第 n 个元素,如果有帮助的话。
如果不将数组分割成 n 块,您将如何高效准确地解决这个问题?
一个简单的方法是使用 pandas
和 expanding
and var(ddof=0)
:
import numpy as np
import pandas as pd
x = np.array([5, 2, 2, 5, 3, 5, 2, 5, 4, 2])
pd.Series(x).expanding().var(ddof=0).to_numpy()
输出:
array([0. , 2.25 , 2. , 2.25 , 1.84 ,
1.88888889, 1.95918367, 1.984375 , 1.77777778, 1.85 ])
我实际上也会采用 pandas 方法。但是,一种使用不需要切片的纯 numpy 的可能解决方案是
def running_mean(x:np.array) -> np.array:
return np.cumsum(x) / np.arange(1,len(x) + 1)
def running_var(x:np.array) -> np.array:
means = running_mean(x)
return ((np.tril(x) - np.triu(means).T) ** 2).sum(axis=1) / np.arange(1,len(x) + 1)
所以基本上使用 运行 均值函数,但是将其转换为三角矩阵并从那里进行数学运算。由于创建了那些大小为 N x N 的三角矩阵,对于大 x,这可能会变得很慢。
我需要计算数据集的样本方差直到第 n 个元素,例如
x = np.random.randint(1, 7, 10)
--> [5 2 2 5 3 5 2 5 4 2]
快速简便的方法是使用 np.var(x) 或 Welfords 算法的实现,但它们只计算整个数据集的方差。 对于我的应用程序,我需要一个数组中的方差元素,以便在第 n 个元素中它将是与数据集中第一个第 n 个数据点的方差。
例如:
x_var[2]
--> variance of [5 2 2]
--> 1.7320508
x_var[9]
--> variance of [5 2 2 5 3 5 2 5 4 2]
--> 2.0555556
我的解决方案是将数组分割成 n 个数组,这样我就可以在每个数组上使用 np.var 来获得 运行 方差。这有效,但速度非常慢。
for i in range(0,n):
x_var[i] = np.var(x[:i])
我已经快速实现了 运行 均值,所以我有一个数组,其中的均值一直到第 n 个条目中的第 n 个元素,如果有帮助的话。
如果不将数组分割成 n 块,您将如何高效准确地解决这个问题?
一个简单的方法是使用 pandas
和 expanding
and var(ddof=0)
:
import numpy as np
import pandas as pd
x = np.array([5, 2, 2, 5, 3, 5, 2, 5, 4, 2])
pd.Series(x).expanding().var(ddof=0).to_numpy()
输出:
array([0. , 2.25 , 2. , 2.25 , 1.84 ,
1.88888889, 1.95918367, 1.984375 , 1.77777778, 1.85 ])
我实际上也会采用 pandas 方法。但是,一种使用不需要切片的纯 numpy 的可能解决方案是
def running_mean(x:np.array) -> np.array:
return np.cumsum(x) / np.arange(1,len(x) + 1)
def running_var(x:np.array) -> np.array:
means = running_mean(x)
return ((np.tril(x) - np.triu(means).T) ** 2).sum(axis=1) / np.arange(1,len(x) + 1)
所以基本上使用 运行 均值函数,但是将其转换为三角矩阵并从那里进行数学运算。由于创建了那些大小为 N x N 的三角矩阵,对于大 x,这可能会变得很慢。