2017-05-31 32 views
1

我想用numpy創建一個2D數組,其中(x,y)處的每個條目都是0或1,並且獲得1的概率由PDF定義,例如2D高斯。通過抽樣創建數組PDF

目標是能夠添加許多這樣的數組,並檢索像直方圖,我可以看到二維高斯峯。

我發現了很多方法來對一個分佈進行採樣(讀取:get back(x,y)對,其中更接近(mu_x,mu_y)的座標更可能),但沒有簡單的方法來填充數組。在numpy/scipy中是否有內置函數可以做到這一點,或者我必須手動完成它(例如迭代數組,如果f(x,y) > threshold將元素設置爲1)?

對於均勻概率分佈,我可以這樣做:

np.random.randint(2, size=(30,30)) 

任何方式爲高斯做到這一點?

回答

2

我不認爲有一個內置的功能,但正如你已經建議,你可以通過比較隨機數與閾值輕鬆實現你想要的。儘管如此,你不應該使用類似for循環的循環,因爲這些循環相當慢。我建議使用np.where進行比較。這裏有一個例子:

首先,我們建立一個網格,計算閾值對每個格點並畫出結果供參考:

import numpy as np 
import scipy.stats as st 
import matplotlib.pyplot as plt 

xEdges = np.linspace(0, 10, 31) 
yEdges = np.linspace(0, 10, 31) 
xMids = (xEdges[:-1]+xEdges[1:])/2. 
yMids = (yEdges[:-1]+yEdges[1:])/2. 
xMesh, yMesh = np.meshgrid(xMids, yMids) 

rv = st.multivariate_normal(mean=[5, 5], cov=[[2,0],[0,2]]) 
threshold = rv.pdf(np.stack((xMesh, yMesh), axis=2)) 

plt.axes().set_aspect('equal') 
plt.pcolormesh(xMesh, yMesh, threshold) 
plt.colorbar() 
plt.xlabel("x") 
plt.ylabel("y") 
plt.show() 

輸出(雙變量高斯分佈,任意歸我真的不明白你想要什麼比較正常化的例子,但因爲這只是一個因素,我剛剛離開是是):

enter image description here

現在我們可以比較均勻分佈的隨機數的數組是通過使用np.where,將柵格形狀的補間0和1與閾值進行比較。當條件滿足時,在結果中的相關條目設置爲1,elseway 0:

hist = np.where(np.random.rand(30, 30)<threshold, 1, 0) 
plt.axes().set_aspect('equal') 
plt.pcolormesh(xMesh, yMesh, hist) 
plt.colorbar() 
plt.xlabel("x") 
plt.ylabel("y") 
plt.show() 

1現在嘗試後,你不能真正看到,這是工作,但hist包含你想要什麼:

enter image description here

for _ in range(9999): 
    hist += np.where(np.random.rand(30, 30)<threshold, 1, 0) 
plt.axes().set_aspect('equal') 
plt.pcolormesh(xMesh, yMesh, hist/10000.) 
plt.colorbar() 
plt.xlabel("x") 
plt.ylabel("y") 
plt.show() 

後10000次嘗試,你已經可以很好地看到分佈造型:

enter image description here

for _ in range(90000): 
    hist += np.where(np.random.rand(30, 30)<threshold, 1, 0) 
plt.axes().set_aspect('equal') 
plt.pcolormesh(xMesh, yMesh, hist/100000.) 
plt.colorbar() 
plt.xlabel("x") 
plt.ylabel("y") 
plt.show() 

和平均100000嘗試,分佈在解析分佈函數旁邊沒有區別:

enter image description here