Python 如何生成整数的随机正态分布
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/37411633/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to generate a random normal distribution of integers
提问by Ghilas BELHADJ
How to generate a random integer as with np.random.randint()
, but with a normal distribution around 0.
如何生成与 一样的随机整数np.random.randint()
,但正态分布在 0 左右。
np.random.randint(-10, 10)
returns integers with a discrete uniform distribution
np.random.normal(0, 0.1, 1)
returns floats with a normal distribution
np.random.randint(-10, 10)
返回具有离散均匀分布的整数
np.random.normal(0, 0.1, 1)
返回具有正态分布的浮点数
What I want is a kind of combination between the two functions.
我想要的是两种功能之间的一种组合。
回答by ayhan
One other possible way to get a discrete distribution that looks likethe normal distribution is to draw from a multinomial distribution where the probabilities are calculated from a normal distribution.
获得看起来像正态分布的离散分布的另一种可能方法是从多项分布中提取,其中概率是根据正态分布计算的。
import scipy.stats as ss
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(-10, 11)
xU, xL = x + 0.5, x - 0.5
prob = ss.norm.cdf(xU, scale = 3) - ss.norm.cdf(xL, scale = 3)
prob = prob / prob.sum() #normalize the probabilities so their sum is 1
nums = np.random.choice(x, size = 10000, p = prob)
plt.hist(nums, bins = len(x))
Here, np.random.choice
picks an integer from [-10, 10]. The probability for selecting an element, say 0, is calculated by p(-0.5 < x < 0.5) where x is a normal random variable with mean zero and standard deviation 3. I chooce std. dev. as 3 because this way p(-10 < x < 10) is almost 1.
在这里,np.random.choice
从 [-10, 10] 中选择一个整数。选择一个元素的概率,比如 0,由 p(-0.5 < x < 0.5) 计算,其中 x 是一个正态随机变量,均值为 0,标准差为 3。我选择 std。开发 为 3,因为这样 p(-10 < x < 10) 几乎等于 1。
The result looks like this:
结果如下所示:
回答by bakkal
It may be possible to generate a similar distribution from a Truncated Normal Distributionthat is rounded up to integers. Here's an example with scipy's truncnorm().
可以从四舍五入为整数的截断正态分布生成类似的分布。这是 scipy 的truncnorm()示例。
import numpy as np
from scipy.stats import truncnorm
import matplotlib.pyplot as plt
scale = 3.
range = 10
size = 100000
X = truncnorm(a=-range/scale, b=+range/scale, scale=scale).rvs(size=size)
X = X.round().astype(int)
Let's see what it looks like
让我们看看它长什么样
bins = 2 * range + 1
plt.hist(X, bins)
回答by stephan
The accepted answer here works, but I tried Will Vousden's solution and it works well too:
此处接受的答案有效,但我尝试了 Will Vousden 的解决方案,并且效果很好:
import numpy as np
# Generate Distribution:
randomNums = np.random.normal(scale=3, size=100000)
randomInts = np.round(randomNums)
# Plot:
axis = np.arange(start=min(randomInts), stop = max(randomInts) + 1)
plt.hist(randomInts, bins = axis)
回答by CopyPasteIt
Here we start by getting values from the bell curve.
在这里,我们首先从钟形曲线中获取值。
CODE:
代码:
#--------*---------*---------*---------*---------*---------*---------*---------*
# Desc: Discretize a normal distribution centered at 0
#--------*---------*---------*---------*---------*---------*---------*---------*
import sys
import random
from math import sqrt, pi
import numpy as np
import matplotlib.pyplot as plt
def gaussian(x, var):
k1 = np.power(x, 2)
k2 = -k1/(2*var)
return (1./(sqrt(2. * pi * var))) * np.exp(k2)
#--------*---------*---------*---------*---------*---------*---------*---------#
while 1:# M A I N L I N E #
#--------*---------*---------*---------*---------*---------*---------*---------#
# # probability density function
# # for discrete normal RV
pdf_DGV = []
pdf_DGW = []
var = 9
tot = 0
# # create 'rough' gaussian
for i in range(-var - 1, var + 2):
if i == -var - 1:
r_pdf = + gaussian(i, 9) + gaussian(i - 1, 9) + gaussian(i - 2, 9)
elif i == var + 1:
r_pdf = + gaussian(i, 9) + gaussian(i + 1, 9) + gaussian(i + 2, 9)
else:
r_pdf = gaussian(i, 9)
tot = tot + r_pdf
pdf_DGV.append(i)
pdf_DGW.append(r_pdf)
print(i, r_pdf)
# # amusing how close tot is to 1!
print('\nRough total = ', tot)
# # no need to normalize with Python 3.6,
# # but can't help ourselves
for i in range(0,len(pdf_DGW)):
pdf_DGW[i] = pdf_DGW[i]/tot
# # print out pdf weights
# # for out discrte gaussian
print('\npdf:\n')
print(pdf_DGW)
# # plot random variable action
rv_samples = random.choices(pdf_DGV, pdf_DGW, k=10000)
plt.hist(rv_samples, bins = 100)
plt.show()
sys.exit()
OUTPUT:
输出:
-10 0.0007187932912256041
-9 0.001477282803979336
-8 0.003798662007932481
-7 0.008740629697903166
-6 0.017996988837729353
-5 0.03315904626424957
-4 0.05467002489199788
-3 0.0806569081730478
-2 0.10648266850745075
-1 0.12579440923099774
0 0.1329807601338109
1 0.12579440923099774
2 0.10648266850745075
3 0.0806569081730478
4 0.05467002489199788
5 0.03315904626424957
6 0.017996988837729353
7 0.008740629697903166
8 0.003798662007932481
9 0.001477282803979336
10 0.0007187932912256041
Rough total = 0.9999715875468381
pdf:
[0.000718813714486599, 0.0014773247784004072, 0.003798769940305483, 0.008740878047691289, 0.017997500190860556, 0.033159988420867426, 0.05467157824565407, 0.08065919989878699, 0.10648569402724471, 0.12579798346031068, 0.13298453855078374, 0.12579798346031068, 0.10648569402724471, 0.08065919989878699, 0.05467157824565407, 0.033159988420867426, 0.017997500190860556, 0.008740878047691289, 0.003798769940305483, 0.0014773247784004072, 0.000718813714486599]