web-dev-qa-db-ja.com

SQLiteの標準偏差

SQLiteのドキュメントを検索しましたが、何も見つかりませんでしたが、Googleでも検索したところ、いくつかの結果が表示されました。

SQLiteには標準偏差関数が組み込まれていますか?

21
Alix Axel

ウェルフォードの方法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);

それはPHP($dbはPDOオブジェクトです)が、別の言語に移植するのは簡単なはずです。

SQLiteはsooooかっこいいです。 <3

4
Alix Axel

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

ただし、標準偏差を取得するには、平方根を計算する必要があります。

27
Anonymous

SQLiteでサポートされている集計関数は次のとおりです。

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

STDEVはリストにありません。

ただし、モジュールextension-functions.c in このページ にはSTDEV関数が含まれています。

15
Robert Harvey

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])

これは印刷されます:

avg: 3.000000
stdev: 1.581139

MySQLと比較してください: http://sqlfiddle.com/#!2/ad42f3/3/

11
alex.forencich

ちょっとしたトリック

select ((sum(value)*sum(value) - sum(value * value))/((count(*)-1)*(count(*)))) 
from the_table ;

残っているのは、外部のsqrtを計算することだけです。

3
user293074

いいえ、同じ問題を検索し、アプリケーション(PHP)で計算を行う必要がなくなりました。

2
tpow

分散式を使用V(X) = E(X ^ 2)-E(X)^2。SQLsqliteの場合

SELECT AVG(col*col) - AVG(col)*AVG(col) FROM table

標準偏差を取得するには、平方根V(X)^(1/2)を取る必要があります。

1
Don Juan

計算する標準偏差のバージョンは指定しませんが、sum()とcount()の集計関数の組み合わせを使用して、どちらのバージョンの分散(標準偏差の2乗)も計算できます。

select  
(count(val)*sum(val*val) - (sum(val)*sum(val)))/((count(val)-1)*(count(val))) as sample_variance,
(count(val)*sum(val*val) - (sum(val)*sum(val)))/((count(val))*(count(val))) as population_variance
from ... ;

標準偏差を取得するには、これらの平方根をとる必要があります。

0
Ryan

python関数にエラー検出を追加しました

class StdevFunc:
    """
    For use as an aggregate function in SQLite
    """
    def __init__(self):
        self.M = 0.0
        self.S = 0.0
        self.k = 0

    def step(self, value):
        try:
            # automatically convert text to float, like the rest of SQLite
            val = float(value) # if fails, skips this iteration, which also ignores nulls
            tM = self.M
            self.k += 1
            self.M += ((val - tM) / self.k)
            self.S += ((val - tM) * (val - self.M))
        except:
            pass

    def finalize(self):
        if self.k <= 1: # avoid division by zero
            return none
        else:
            return math.sqrt(self.S / (self.k-1))
0
Rick Shory