SQLite的标准偏差

Ali*_*xel 21 sqlite function standard-deviation

我搜索过SQLite文档并找不到任何内容,但我也在谷歌上搜索了一些结果.

SQLite是否有任何内置的标准偏差功能?

小智 27

您可以计算SQL中的方差:

create table t (row int);
insert into t values (1),(2),(3);
SELECT AVG((t.row - sub.a) * (t.row - sub.a)) as var from t, 
    (SELECT AVG(row) AS a FROM t) AS sub;
0.666666666666667
Run Code Online (Sandbox Code Playgroud)

但是,您仍然需要计算平方根以获得标准偏差.

  • 应该注意的是,该算法计算方差的有偏版本。方差应始终计算为 $\frac{1}{n-1} \sum(X_i - \bar{X})$,但您要除以 $n$ 而不是 $n-1$。由于 $n \rightarrow \infty$ 这种差异变得可以忽略不计,但人们会想知道为什么您的差异与任何标准软件都不匹配...... (3认同)
  • 对不起,我以为这会渲染乳胶。用简单的英语来说,这种计算方差的方式是不正确的,但并非绝对可怕。对于大量观察,此版本与通常方法之间的差异将相当小,但您将不得不解释为什么您的差异与标准软件输出不匹配。您可以告诉统计学家您使用的是有偏差的方差版本,但我发现如果您的方差与标准软件不匹配,那么不太喜欢定量的人会感到不舒服。 (2认同)

Rob*_*vey 15

SQLite支持的聚合函数在这里:

http://www.sqlite.org/lang_aggfunc.html

STDEV不在列表中.

然而,该模块extension-functions.c该页面包含一个STDEV功能.


ale*_*ich 10

sqlite中仍然没有内置的stdev函数.但是,您可以定义(如Alix已完成的)用户定义的聚合器函数.这是Python中的完整示例:

import sqlite3
import math

class StdevFunc:
    def __init__(self):
        self.M = 0.0
        self.S = 0.0
        self.k = 1

    def step(self, value):
        if value is None:
            return
        tM = self.M
        self.M += (value - tM) / self.k
        self.S += (value - tM) * (value - self.M)
        self.k += 1

    def finalize(self):
        if self.k < 3:
            return None
        return math.sqrt(self.S / (self.k-2))

with sqlite3.connect(':memory:') as con:

    con.create_aggregate("stdev", 1, StdevFunc)

    cur = con.cursor()

    cur.execute("create table test(i)")
    cur.executemany("insert into test(i) values (?)", [(1,), (2,), (3,), (4,), (5,)])
    cur.execute("insert into test(i) values (null)")
    cur.execute("select avg(i) from test")
    print("avg: %f" % cur.fetchone()[0])
    cur.execute("select stdev(i) from test")
    print("stdev: %f" % cur.fetchone()[0])
Run Code Online (Sandbox Code Playgroud)

这将打印:

avg: 3.000000
stdev: 1.581139
Run Code Online (Sandbox Code Playgroud)

与MySQL比较:http://sqlfiddle.com/#!2/ad42f3/3/0


小智 7

使用方差公式 V(X) = E(X^2) - E(X)^2。在 SQL 中

SELECT AVG(col*col) - AVG(col)*AVG(col) FROM table
Run Code Online (Sandbox Code Playgroud)

要获得标准差,您需要取平方根 V(X)^(1/2)


Ali*_*xel 6

我将Welford 的方法(与 相同extension-functions.c)实现为 SQLite UDF:

$db->sqliteCreateAggregate('stdev',
    function (&$context, $row, $data) // step callback
    {
        if (isset($context) !== true) // $context is null at first
        {
            $context = array
            (
                'k' => 0,
                'm' => 0,
                's' => 0,
            );
        }

        if (isset($data) === true) // the standard is non-NULL values only
        {
            $context['s'] += ($data - $context['m']) * ($data - ($context['m'] += ($data - $context['m']) / ++$context['k']));
        }

        return $context;
    },
    function (&$context, $row) // fini callback
    {
        if ($context['k'] > 0) // return NULL if no non-NULL values exist
        {
            return sqrt($context['s'] / $context['k']);
        }

        return null;
    },
1);
Run Code Online (Sandbox Code Playgroud)

这是 PHP 中的($db是 PDO 对象),但移植到另一种语言应该很简单。

SQLite酷了。<3