【问题标题】:Is there a fast (and accurate) way to calculate the sample variance of a data-set till the n-th element?有没有一种快速(准确)的方法来计算数据集的样本方差,直到第 n 个元素?
【发布时间】:2022-01-17 12:59:11
【问题描述】:

我需要计算数据集的样本方差,直到第 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 块的情况下,如何有效且准确地解决这个问题?

【问题讨论】:

标签: python arrays numpy statistics variance


【解决方案1】:

一个简单的方法是将pandasexpandingvar(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      ])

【讨论】:

    【解决方案2】:

    我实际上也会采用 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,这可能会变得很慢。

    【讨论】:

    • 这比因为我有 10e6-10e8 范围内的数组
    猜你喜欢
    • 1970-01-01
    • 2014-11-18
    • 1970-01-01
    • 2011-08-26
    • 2020-11-20
    • 2013-02-24
    • 2011-05-14
    • 2011-01-21
    • 2021-04-25
    相关资源
    最近更新 更多