PostgreSQL 聚合函数讲解 - 3 总体|样本 方差, 标准方差

PostgreSQL自带了一些常用的统计学聚合函数, 非常好用.
本文介绍一下方差和标准差的一些聚合函数.

总体方差 : population covariance
总体标准差 : population standard deviation
样本方差 : sample covariance
样本标准差 : sample standard deviation
均值 :  mean

样本均值和样本方差的介绍 :
http://en.wikipedia.org/wiki/Sample_mean_and_sample_covariance
均值介绍 :
http://en.wikipedia.org/wiki/Mean

对方差, 标准差, 均值不了解的话, 建议参考网易公开课, 统计学.
浅显易懂.
http://v.163.com/special/Khan/khstatistics.html
http://v.ku6.com/playlist/index_6598382.html

PostgreSQL计算方差, 标准差的聚合函数如下 :
http://www.postgresql.org/docs/devel/static/functions-aggregate.html

其中stddev和variance是stddev_samp和var_samp的别名.
这些函数用于计算数据集的总体/样本 方差,总体/样本 标准差.
例如 :
1,2,3,100 这组数据共4个值, 总体均值和样本均值分别为 :
(1+2+3+100)/4 = 26.5
总体方差 : ((1-26.5)^2 + (2-26.5)^2 + (3-26.5)^2 + (100-26.5)^2)/4 = 1801.25
样本方差 : ((1-26.5)^2 + (2-26.5)^2 + (3-26.5)^2 + (100-26.5)^2)/(4-1) = 2401.6666....
总体标准差 : 平方根(总体方差) = 42.4411357058220109
样本标准差 : 平方根(样本方差) = 49.0068022489395513
使用PostgreSQL计算如下 :
postgres=# select variance(id) from (values(1),(2),(3),(100)) as t(id);
       variance
-----------------------
 2401.6666666666666667
(1 row)
postgres=# select var_pop(id) from (values(1),(2),(3),(100)) as t(id);
        var_pop
-----------------------
 1801.2500000000000000
(1 row)
postgres=# select var_samp(id) from (values(1),(2),(3),(100)) as t(id);
       var_samp
-----------------------
 2401.6666666666666667
(1 row)
postgres=# select stddev(id) from (values(1),(2),(3),(100)) as t(id);
       stddev
---------------------
 49.0068022489395513
(1 row)
postgres=# select stddev_pop(id) from (values(1),(2),(3),(100)) as t(id);
     stddev_pop
---------------------
 42.4411357058220109
(1 row)
postgres=# select stddev_samp(id) from (values(1),(2),(3),(100)) as t(id);
     stddev_samp
---------------------
 49.0068022489395513
(1 row)

[参考]
1. src/backend/utils/adt/float.c
/*
 *              =========================
 *              FLOAT AGGREGATE OPERATORS
 *              =========================
 *
 *              float8_accum            - accumulate for AVG(), variance aggregates, etc.
 *              float4_accum            - same, but input data is float4
 *              float8_avg                      - produce final result for float AVG()
 *              float8_var_samp         - produce final result for float VAR_SAMP()
 *              float8_var_pop          - produce final result for float VAR_POP()
 *              float8_stddev_samp      - produce final result for float STDDEV_SAMP()
 *              float8_stddev_pop       - produce final result for float STDDEV_POP()
 *
 * The transition datatype for all these aggregates is a 3-element array
 * of float8, holding the values N, sum(X), sum(X*X) in that order.
 *
 * Note that we represent N as a float to avoid having to build a special
 * datatype.  Given a reasonable floating-point implementation, there should
 * be no accuracy loss unless N exceeds 2 ^ 52 or so (by which time the
 * user will have doubtless lost interest anyway...)
 */
..................
Datum
float8_var_pop(PG_FUNCTION_ARGS)
{
        ArrayType  *transarray = PG_GETARG_ARRAYTYPE_P(0);
        float8     *transvalues;
        float8          N,
                                sumX,
                                sumX2,
                                numerator;

        transvalues = check_float8_array(transarray, "float8_var_pop", 3);
        N = transvalues[0];
        sumX = transvalues[1];
        sumX2 = transvalues[2];

        /* Population variance is undefined when N is 0, so return NULL */
        if (N == 0.0)
                PG_RETURN_NULL();

        numerator = N * sumX2 - sumX * sumX;
        CHECKFLOATVAL(numerator, isinf(sumX2) || isinf(sumX), true);

        /* Watch out for roundoff error producing a negative numerator */
        if (numerator <= 0.0)
                PG_RETURN_FLOAT8(0.0);

        PG_RETURN_FLOAT8(numerator / (N * N));
}

Datum
float8_var_samp(PG_FUNCTION_ARGS)
{
        ArrayType  *transarray = PG_GETARG_ARRAYTYPE_P(0);
        float8     *transvalues;
        float8          N,
                                sumX,
                                sumX2,
                                numerator;

        transvalues = check_float8_array(transarray, "float8_var_samp", 3);
        N = transvalues[0];
        sumX = transvalues[1];
        sumX2 = transvalues[2];

        /* Sample variance is undefined when N is 0 or 1, so return NULL */
        if (N <= 1.0)
                PG_RETURN_NULL();

        numerator = N * sumX2 - sumX * sumX;
        CHECKFLOATVAL(numerator, isinf(sumX2) || isinf(sumX), true);

        /* Watch out for roundoff error producing a negative numerator */
        if (numerator <= 0.0)
                PG_RETURN_FLOAT8(0.0);

        PG_RETURN_FLOAT8(numerator / (N * (N - 1.0)));
}

Datum
float8_stddev_pop(PG_FUNCTION_ARGS)
{
        ArrayType  *transarray = PG_GETARG_ARRAYTYPE_P(0);
        float8     *transvalues;
        float8          N,
                                sumX,
                                sumX2,
                                numerator;

        transvalues = check_float8_array(transarray, "float8_stddev_pop", 3);
        N = transvalues[0];
        sumX = transvalues[1];
        sumX2 = transvalues[2];

        /* Population stddev is undefined when N is 0, so return NULL */
        if (N == 0.0)
                PG_RETURN_NULL();

        numerator = N * sumX2 - sumX * sumX;
        CHECKFLOATVAL(numerator, isinf(sumX2) || isinf(sumX), true);

        /* Watch out for roundoff error producing a negative numerator */
        if (numerator <= 0.0)
                PG_RETURN_FLOAT8(0.0);

        PG_RETURN_FLOAT8(sqrt(numerator / (N * N)));
}

Datum
float8_stddev_samp(PG_FUNCTION_ARGS)
{
        ArrayType  *transarray = PG_GETARG_ARRAYTYPE_P(0);
        float8     *transvalues;
        float8          N,
                                sumX,
                                sumX2,
                                numerator;

        transvalues = check_float8_array(transarray, "float8_stddev_samp", 3);
        N = transvalues[0];
        sumX = transvalues[1];
        sumX2 = transvalues[2];

        /* Sample stddev is undefined when N is 0 or 1, so return NULL */
        if (N <= 1.0)
                PG_RETURN_NULL();

        numerator = N * sumX2 - sumX * sumX;
        CHECKFLOATVAL(numerator, isinf(sumX2) || isinf(sumX), true);

        /* Watch out for roundoff error producing a negative numerator */
        if (numerator <= 0.0)
                PG_RETURN_FLOAT8(0.0);

        PG_RETURN_FLOAT8(sqrt(numerator / (N * (N - 1.0))));
}
时间: 2024-10-31 08:16:35

PostgreSQL 聚合函数讲解 - 3 总体|样本 方差, 标准方差的相关文章

PostgreSQL 聚合函数讲解 - 4 总体协方差, 样本协方差

1. 数学期望值, 平均值, mean http://zh.wikipedia.org/wiki/%E6%9C%9F%E6%9C%9B%E5%80%BC 表示: E[X], 即X变量的平均值. 也用miu表示 : μ=E[X] PostgreSQL中举例 :  postgres=# select avg(c1) from (values(null),(1),(2)) as t(c1);         avg          --------------------  1.5000000000

PostgreSQL 聚合函数讲解 - 5 线性回归

首先讲个线性回归分析linear regression (最小二乘法least-squares-fit)的小故事(取自百度) :  1801年,意大利天文学家朱赛普·皮亚齐发现了第一颗小行星谷神星.经过40天的跟踪观测后,由于谷神星运行至太阳背后,使得皮亚齐失去了谷神星的位置.随后全世界的科学家利用皮亚齐的观测数据开始寻找谷神星,但是根据大多数人计算的结果来寻找谷神星都没有结果.时年24岁的高斯也计算了谷神星的轨道.奥地利天文学家海因里希·奥尔伯斯根据高斯计算出来的轨道重新发现了谷神星. 高斯使

PostgreSQL 聚合函数讲解 - 7 窗口反聚合

聚合函数的最后一个分类, Hypothetical-Set Aggregate Functions. 这类聚合函数还有对应的窗口函数, 首先来看一下对应窗口函数的用法. rank() bigint rank of the current row with gaps; same as row_number of its first peer dense_rank() bigint rank of the current row without gaps; this function counts

PostgreSQL 聚合函数讲解 - 1 常用聚合函数

PostgreSQL支持较多的聚合函数, 以PostgreSQL 9.4为例, 支持例如一般性的聚合, 统计学科的聚合, 排序集聚合, 假象集聚合等. 本文将对一般性聚合函数举例说明其功能和用法. 聚合函数有哪些,见 : http://www.postgresql.org/docs/9.4/static/functions-aggregate.html 以上所有聚合函数, 当没有行输入时, 除了count返回0, 其他都返回null. 使用sum, array_agg时, 当没有行输入, 返回N

PostgreSQL 聚合函数讲解 - 6 分组排序聚合

分组排序聚合的例子. Table 9-51. Ordered-Set Aggregate Functions Function Direct Argument Type(s) Aggregated Argument Type(s) Return Type Description mode() WITHIN GROUP (ORDER BYsort_expression)   any sortable type same as sort expression returns the most fre

《卸甲笔记》-PostgreSQL和Oracle的SQL差异分析之三:rownum和聚合函数

PostgreSQL是世界上功能最强大的开源数据库,在国内得到了越来越多机构和开发者的青睐和应用.随着PostgreSQL的应用越来越广泛,Oracle向PostgreSQL数据库的数据迁移需求也越来越多.数据库之间数据迁移的时候,首先是迁移数据,然后就是SQL.存储过程.序列等程序中不同的数据库中数据的使用方式的转换.下面根据自己的理解和测试,写了一些SQL以及数据库对象转换方面的文章,不足之处,尚请多多指教. rownum rownum是Oracle内部的一个伪列,用来表示数据在结果集中的行

PostgreSQL和Oracle的SQL差异分析之rownum和聚合函数

PostgreSQL是世界上功能最强大的开源数据库,在国内得到了越来越多机构和开发者的青睐和应用.随着PostgreSQL的应用越来越广泛,Oracle向PostgreSQL数据库的数据迁移需求也越来越多.数据库之间数据迁移的时候,首先是迁移数据,然后就是SQL.存储过程.序列等程序中不同的数据库中数据的使用方式的转换.下面根据自己的理解和测试,写了一些SQL以及数据库对象转换方面的文章,不足之处,尚请多多指教. rownum rownum是Oracle内部的一个伪列,用来表示数据在结果集中的行

MySQL数据库学习笔记(四)----MySQL聚合函数、控制流程函数(含navicat软件的介绍)

[正文] 一.navicat的引入:(第三方可视化的客户端,方便MySQL数据库的管理和维护) NavicatTM是一套快速.可靠并价格相宜的数据库管理工具,专为简化数据库的管理及降低系统管理成本而设.它的设计符合数据库管理员.开发人员及中小企业的需要.Navicat 是以直觉化的图形用户界面而建的,让你可以以安全并且简单的方式创建.组织.访问并共用信息. Navicat 是闻名世界.广受全球各大企业.政府机构.教育机构所信赖,更是各界从业员每天必备的工作伙伴,被公认为全球最受欢迎的MySQL前

Postgres-XC 聚合原理 以及 如何编写聚合函数

Postgres-XC聚合与PostgreSQL的聚合有一定的区别, 因为Postgres-XC的数据存储在datanode, 聚合时数据可能分布在多个datanode上. Postgres-XC支持传统的聚合方法, 聚合操作可以将数据从所有的数据节点传到coordinator节点后, 在coordinator节点进行聚合. 但是这种方法对于数据量较大的情况效率明显偏低. Postgres-XC还支持另一种聚合方式, 就是数据在各自的datanode执行, 形成结果后, 将datanode聚合的