Numpy 从给定的二维分布函数中提取随机数据

Numpy 从给定的二维分布函数中提取随机数据,numpy,scipy,probability,static-methods,probability-theory,Numpy,Scipy,Probability,Static Methods,Probability Theory,我有一个理论分布,我想在2D空间中随机取样,得到以下分布: def p(z,m): E = { 'ft':0.55, 'alpha': 2.99, 'z0':0.191, 'km':0.089, 'kt':0.25 } S = { 'ft':0.39, 'alpha': 2.15, 'z0':0.121, 'km':0.093, 'kt':-0.175 } I={ 'ft':0.06, 'alpha': 1.77, 'z0':0.045, 'km':0.096, 'kt'

我有一个理论分布,我想在2D空间中随机取样,得到以下分布:

def p(z,m):
    E = { 'ft':0.55, 'alpha': 2.99, 'z0':0.191, 'km':0.089, 'kt':0.25 }
    S = { 'ft':0.39, 'alpha': 2.15, 'z0':0.121, 'km':0.093, 'kt':-0.175 }
    I={ 'ft':0.06, 'alpha': 1.77, 'z0':0.045, 'km':0.096, 'kt':0.0 }
    Evalue=E['ft']*np.exp(-1*E['kt']*(m-20))*z**E['alpha']*np.exp(-1*(z/(E['z0']+E['km']*(m-20)))**E['alpha'])
    Svalue=S['ft']*np.exp(-1*S['kt']*(m-20))*z**S['alpha']*np.exp(-1*(z/(S['z0']+S['km']*(m-20)))**S['alpha'])
    Ivalue=I['ft']*np.exp(-1*I['kt']*(m-20))*z**I['alpha']*np.exp(-1*(z/(I['z0']+I['km']*(m-20)))**I['alpha'])
    value=Evalue+Svalue+Ivalue
    return value
更新: 我发现逆变换采样是从概率分布中采样数据的合适方法。
如何在python中为2D数据编写此方法,或者是否有任何库可供我使用?

如果您希望从p(z,m)中随机采样一个值,那么实现此方法的简单方法是使用python中的“随机”模块。我用numpy版本的random展示了这个想法:

import numpy as np
import matplotlib.pyplot as plt

def p(z,m):
    E = { 'ft':0.55, 'alpha': 2.99, 'z0':0.191, 'km':0.089, 'kt':0.25 }
    S = { 'ft':0.39, 'alpha': 2.15, 'z0':0.121, 'km':0.093, 'kt':-0.175 }
    I={ 'ft':0.06, 'alpha': 1.77, 'z0':0.045, 'km':0.096, 'kt':0.0 }
    Evalue=E['ft']*np.exp(-1*E['kt']*(m-20))*z**E['alpha']*np.exp(-1*(z/(E['z0']+E['km']*(m-20)))**E['alpha'])
    Svalue=S['ft']*np.exp(-1*S['kt']*(m-20))*z**S['alpha']*np.exp(-1*(z/(S['z0']+S['km']*(m-20)))**S['alpha'])
    Ivalue=I['ft']*np.exp(-1*I['kt']*(m-20))*z**I['alpha']*np.exp(-1*(z/(I['z0']+I['km']*(m-20)))**I['alpha'])
    value=Evalue+Svalue+Ivalue
    return value

# Define the number of iterations you want for each variable    
num_iter_m = 50
num_iter_z = 50

# I then set rand_m to go from 20 to 30, as your function fails for <20
rand_m = (np.random.random(num_iter_m)*10)+20

# z goes from the range 0 - 1
rand_z = (np.random.random(num_iter_z))

# Note, I am sampling from a uniform distribution for m and z. You can use more complicated functions, i.e., Gaussian/Normal shapes or even user defined.

rand_p = np.zeros((len(rand_z), len(rand_m)))

# Fill a grid with the random p(z,m) values
for i in range(len(rand_z)):
  for j in range(len(rand_m)):
    rand_p[i][j] = p(rand_z[i], rand_m[j])

# Plot
fig = plt.figure(0)

ax1 = fig.add_subplot(211)
ax1.scatter(rand_z, rand_m)
ax1.set_xlabel("z")
ax1.set_ylabel("m")

ax2 = fig.add_subplot(212)
cf = ax2.contourf(rand_z, rand_m, rand_p)
ax2.set_xlabel("z")
ax2.set_ylabel("m")

colbar = plt.colorbar(cf)
colbar.set_label("p(z,m)")

plt.show()
将numpy导入为np
将matplotlib.pyplot作为plt导入
defp(z,m):
E={'ft':0.55,'alpha':2.99,'z0':0.191,'km':0.089,'kt':0.25}
S={'ft':0.39,'alpha':2.15,'z0':0.121,'km':0.093,'kt':-0.175}
I={'ft':0.06,'alpha':1.77,'z0':0.045,'km':0.096,'kt':0.0}
Evalue=E['ft']*np.exp(-1*E['kt']*(m-20))*z**E['alpha']*np.exp(-1*(z/(E['z0']+E['km']*(m-20))**E['alpha']))
S值=S['ft']*np.exp(-1*S['kt']*(m-20))*z**S['alpha']*np.exp(-1*(z/(S['z0']+S['km']*(m-20))**S['alpha']))
Ivalue=I['ft']*np.exp(-1*I['kt']*(m-20))*z**I['alpha']*np.exp(-1*(z/(I['z0']+I['km']*(m-20))**I['alpha']))
value=Evalue+Svalue+Ivalue
返回值
#定义每个变量所需的迭代次数
数量=50
num_iter_z=50

#然后我将rand_m设置为从20到30,因为函数在中失败。请看一下马尔可夫链蒙特卡罗(MCMC)方法。基本上你在(z,m)点的空间内跳跃。无论你在哪里,你总是接受一个增加p(z,m)的跳跃。你接受一个跳跃,它以一定的概率减小p(z,m)。有一个Python库PyMC来执行该过程。

这似乎不是解决OP提出的问题的方法。“如果您想通过2D函数p(z,m)对z和m进行加权采样”--我很确定这就是他想要的。二维中的
逆变换采样
怎么样,但问题是如何对复杂的二维分布进行逆变换
CDF
。不,逆变换采样不能直接应用于超过一维。您可以构造p(m | z)和p(z),然后通过逆变换方法从p(z)和p(m | z)中首先采样,但这是一个不必要的复杂性。最好通过MCMC直接解决问题。或者只编写代码,这非常简单。如果没有大的速度限制,最简单的方法是使用拒绝方法。