在Python中生成三维高斯分布

时间:2014-09-08 08:59:45

标签: python numpy gaussian

我想在Python中生成高斯分布,x和y维度表示位置,z维度表示特定数量的大小。

分布的最大值为2e6,标准差sigma = 0.025。

在MATLAB中,我可以这样做:

x1 = linspace(-1,1,30);
x2 = linspace(-1,1,30);

mu = [0,0];
Sigma = [.025,.025];

[X1,X2] = meshgrid(x1,x2);
F = mvnpdf([X1(:) X2(:)],mu,Sigma);
F = 314159.153*reshape(F,length(x2),length(x1));
surf(x1,x2,F);

在Python中,到目前为止我所拥有的是:

x = np.linspace(-1,1,30)
y = np.linspace(-1,1,30)

mu = (np.median(x),np.median(y))

sigma = (.025,.025)

有一个Numpy函数numpy.random.multivariate_normal可以和MATLAB的mvnpdf做同样的事情,但是我很难找到documentation。特别是在获得numpy.random.multivariate_normal所需的协方差矩阵时。

2 个答案:

答案 0 :(得分:4)

从scipy 0.14开始,您可以使用scipy.stats.multivariate_normal.pdf()

http://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.multivariate_normal.html

import numpy as np
from scipy.stats import multivariate_normal

x, y = np.mgrid[-1.0:1.0:30j, -1.0:1.0:30j]
# Need an (N, 2) array of (x, y) pairs.
xy = np.column_stack([x.flat, y.flat])

mu = np.array([0.0, 0.0])

sigma = np.array([.025, .025])
covariance = np.diag(sigma**2)

z = multivariate_normal.pdf(xy, mean=mu, cov=covariance)

# Reshape back to a (30, 30) grid.
z = z.reshape(x.shape)

答案 1 :(得分:0)

我正在开发一个名为 scikit-guess 的 scikit,其中包含一些用于非线性拟合的快速估计例程。它有一个函数 skg.ngauss.model(也可以作为 skg.ngauss_fit.modelskg.ngauss.ngauss_fit.model 访问),它完全符合您的要求。好消息是它不是 PDF,因此您可以开箱即用地设置振幅:

import numpy as np
import skg.ngauss

a = 2e6
mu = 0, 0
sigma = 0.025, 0.025

x = y = np.linspace(-1, 1, 31)

cov = np.diag(sigma)**2
X = np.meshgrid(x, y)

data = skg.ngauss.model(X, a, mu, cov, axis=0)

您需要告诉它 axis=0 因为它会自动为您堆叠数组。为了避免传入那个参数,你可以写

X = np.stack(np.meshgrid(x, y), axis=-1)

您可以绘制结果:

from matplotlib import pyplot as plt
plt.imshow(data)
plt.show()

enter image description here

这不是一个非常令人兴奋的分布,因为传播太小以至于你最终得到的值只有一个像素的 ~2e-5。您可能希望扩大采样空间以获得任何有意义的分辨率。

注意:在撰写本文时,拟合函数 (ngauss_fit) 仍然有问题,但模型已成功测试,只是不在 scikit 中。

免责声明:如果以上内容不明显,我是 scikit-guess 的作者。