PostgreSQL 16 新特性之正态分布随机数函数
Posted 不剪发的Tony老师
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PostgreSQL 16 新特性之正态分布随机数函数相关的知识,希望对你有一定的参考价值。
random() 函数可以用于生成一个大于等于 0 小于等于 1 的随机数,生成的数据遵循平均分布。不过在实际环境中,更多的数据则是遵循正态分布。PostgreSQL 提供了一个扩展模块 tablefunc,可以用于生成遵循正态分布的随机数;或者我们也可以创建存储函数来模拟正态分布的随机数。
考虑到它的实用性,PostgreSQL 16 新增了一个内置的 random_normal() 函数,用于生成这种随机数。我们使用该函数生成 10 个随机数:
select random_normal() as v from generate_series(1, 10);
v |
-------------------+
1.9147182783615317|
-1.7265731892046994|
-0.9601043210986459|
-1.481551351102244|
-1.3763031483133177|
0.11872324455736474|
0.9016843380853512|
0.1288806844184827|
-1.6392171916791691|
0.33770959079074697|
默认参数调用时,random_normal() 函数生成的随机数遵循标准正态分布(均值为 0,标准差为 1)。
以下示例生成的随机数遵循均值为 1、标准差为 5 的正态分布:
select random_normal(1, 5) as v from generate_series(1, 10);
v |
-------------------+
-0.4529440542028027|
5.442251124798599|
6.307851828542196|
4.122825670258253|
-2.186242122101672|
4.767936509571358|
5.172144288566877|
-3.761475521327373|
-2.6431751259304193|
0.19249449162595722|
接下来我们验证一下该函数生成的数据是否遵循正态分布。
SELECT round(random_normal(1, 0.5)::numeric, 1) AS v,
count(*),
repeat('#', (count(*) / 100)::integer)
FROM generate_series(1, 100000)
GROUP BY v
ORDER BY v;
v |count|repeat |
----+-----+-------------------------------------------------------------------------------+
-1.2| 1| |
-1.1| 1| |
-1.0| 3| |
-0.9| 9| |
-0.8| 17| |
-0.7| 21| |
-0.6| 55| |
-0.5| 98| |
-0.4| 132|# |
-0.3| 248|## |
-0.2| 521|##### |
-0.1| 728|####### |
0.0| 1090|########## |
0.1| 1586|############### |
0.2| 2203|###################### |
0.3| 2975|############################# |
0.4| 3878|###################################### |
0.5| 4840|################################################ |
0.6| 5778|######################################################### |
0.7| 6670|################################################################## |
0.8| 7299|######################################################################## |
0.9| 7720|############################################################################# |
1.0| 7960|###############################################################################|
1.1| 7794|############################################################################# |
1.2| 7271|######################################################################## |
1.3| 6745|################################################################### |
1.4| 5796|######################################################### |
1.5| 4796|############################################### |
1.6| 3904|####################################### |
1.7| 3034|############################## |
1.8| 2300|####################### |
1.9| 1567|############### |
2.0| 1175|########### |
2.1| 710|####### |
2.2| 454|#### |
2.3| 267|## |
2.4| 164|# |
2.5| 94| |
2.6| 56| |
2.7| 23| |
2.8| 7| |
2.9| 8| |
3.0| 2| |
从上面的图形可以看出,函数返回的结果是一个正态分布。我们还可以进一步通过均值和标准差进行验证:
WITH RECURSIVE d(n, v) AS (
SELECT 1 AS n, random_normal(1, 0.5) AS v
UNION ALL
SELECT n+1, random_normal(1, 0.5) FROM d WHERE n<100000
)
SELECT count(*), avg(v), stddev(v)
FROM d;
count |avg |stddev |
------+------------------+-------------------+
100000|1.0009116232651825|0.49890904328727353|
以上是关于PostgreSQL 16 新特性之正态分布随机数函数的主要内容,如果未能解决你的问题,请参考以下文章
不用找了,PostgreSQL 12 GA的新特性都在这里!
近 20 年的厚积薄发,PostgreSQL 10 新特性详解