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)
但是,您仍然需要计算平方根以获得标准偏差.
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)
我将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