【问题标题】:Calculate variance in sqlite计算sqlite中的方差
【发布时间】:2014-09-17 16:34:53
【问题描述】:

我想计算表格列的方差。 例如。计算方差的公式包含聚合 和标量函数是:

(SUM((var-AVG(var))*(var-AVG(var))))/(COUNT(var)-1)

其中 var 是计算方差的变量列。

在 Sqlite 中使用此功能的最佳方法是什么,例如:

SELECT (SUM((var-AVG(var))*(var-AVG(var))))/(COUNT(var)-1) AS Variance FROM
TableX

【问题讨论】:

标签: sql sqlite aggregate variance


【解决方案1】:

AVG(var) 的值将在每个要求和的表达式中使用,因此您必须使用子查询单独计算:

SELECT SUM((var-(SELECT AVG(var) FROM TableX))*
           (var-(SELECT AVG(var) FROM TableX)) ) / (COUNT(var)-1) AS Variance
FROM TableX

【讨论】:

    【解决方案2】:

    在部分回应 CL 的上述回答时,我不确定 SELECT AVG(var) FROM TableX 是否被缓存或计算了两次(因为它出现了两次)。对于大型表/视图,这可能会成为一个问题。您可能会喜欢另一种选择:-

    SELECT diff_squared / [n-1] FROM
    (
        SELECT diff * diff AS diff_squared FROM 
        (
            SELECT x - mean AS diff FROM 
            (
                SELECT [Var] AS x FROM TableX
            ) innerData
            LEFT JOIN
            (
                SELECT avg(x) AS mean FROM
                (
                    SELECT [Var] AS x FROM TableX
                ) 
            ) stats
        ) outerData
    ) LEFT JOIN
    (
        SELECT count(x) - 1 AS [n-1] FROM 
        (
            SELECT [Var] AS x FROM TableX
        )   
    ) nMinus1
    

    【讨论】:

      【解决方案3】:

      我需要计算 5 分钟的平均值,并希望在相同的 5 分钟间隔内计算方差。

      简而言之:

      1. 创建 5 分钟平均值的视图
      2. 使用这个视图来计算方差,很像上面这个线程中的 CL,虽然我不同意 COUNT()-1 中的 -1。

      也许不是很优雅,但对我来说更容易捕捉。我使用 LibreOffice Calc(VAR.P 函数)检查了结果。

      数据

      数据位于名为magic 的表中。

      CREATE TABLE magic(
        "dt" TEXT,
        "qccm" REAL,
        PRIMARY KEY (dt)
      );
      

      创建 5 分钟平均值视图

      CREATE VIEW v_magic5m(
      "dt",
      "qccm",
      )
      AS SELECT
      datetime(round(cast(strftime('%s',dt) AS INT)/300)*300, 'unixepoch') AS rndtime,
      avg(qccm),
      GROUP BY rndtime;
      

      计算方差

      WITH tmp
      AS (
          SELECT
          datetime(round(cast(strftime('%s',dt) AS INT)/300)*300, 'unixepoch') AS rnd_dt, 
          qccm
          FROM magic
      )
      SELECT
          tmp.rnd_dt,
          v_magic5m.qccm AS avg_qccm,
          SUM( (tmp.qccm - v_magic5m.qccm)*(tmp.qccm - v_magic5m.qccm) ) / COUNT(tmp.qccm) AS var_qccm
      FROM tmp
      LEFT JOIN v_magic5m ON tmp.rnd_dt=v_magic5m.dt
      GROUP BY tmp.rnd_dt;
      

      输出看起来像这样:

      rnd_dt               avg_qccm          var_qccm        
      -------------------  ----------------  ----------------
      2021-04-28 09:55:00  334.292929292929  765.924293439445
      2021-04-28 10:00:00  332.743333333333  571.924122222222
      2021-04-28 10:05:00  333.04            501.165066666667
      

      【讨论】:

        猜你喜欢
        • 2020-07-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-28
        • 2019-03-30
        • 1970-01-01
        • 2021-06-30
        • 2014-04-19
        相关资源
        最近更新 更多