[英]How can I generate a random sample of bin counts given a sequence of bin probabilities?
我有一個整數,需要根據概率分布分成多個 bin。 例如,如果我有N=100
對象進入[0.02, 0.08, 0.16, 0.29, 0.45]
那么你可能會得到[1, 10, 20, 25, 44]
。
import numpy as np
# sample distribution
d = np.array([x ** 2 for x in range(1,6)], dtype=float)
d = d / d.sum()
dcs = d.cumsum()
bins = np.zeros(d.shape)
N = 100
for roll in np.random.rand(N):
# grab the first index that the roll satisfies
i = np.where(roll < dcs)[0][0]
bins[i] += 1
實際上,N 和我的 bin 數量非常大,因此循環並不是真正可行的選擇。 有什么方法可以矢量化此操作以加快速度嗎?
您可以通過獲取 cumsum 將您的 PDF 轉換為 CDF,使用它來定義一組介於 0 和 1 之間的 bin,然后使用這些 bin 來計算N長隨機均勻向量的直方圖:
cdf = np.cumsum([0, 0.02, 0.08, 0.16, 0.29, 0.45]) # leftmost bin edge = 0
counts, edges = np.histogram(np.random.rand(100), bins=cdf)
print(counts)
# [ 4, 8, 16, 30, 42]
可以使用np.bincount
用於合並動作地連同np.searchsorted
執行的等效roll < dcs
操作。 這是實現這些承諾的實現 -
bins = np.bincount(np.searchsorted(dcs,np.random.rand(N),'right'))
使用給定參數的運行時測試 -
In [72]: %%timeit
...: for roll in np.random.rand(N):
...: # grab the first index that the roll satisfies
...: i = np.where(roll < dcs)[0][0]
...: bins[i] += 1
...:
1000 loops, best of 3: 721 µs per loop
In [73]: %%timeit
...: np.bincount(np.searchsorted(dcs,np.random.rand(N),'right'))
...:
100000 loops, best of 3: 13.5 µs per loop
另一種方法來做到這一點:
import numpy as np
p = [0.02, 0.08, 0.16, 0.29, 0.45]
np.bincount(np.random.choice(range(len(p)), size=100, p=p), minlength=len(p))
# array([ 1, 6, 16, 25, 52])
似乎不需要分配長度為 100 的數組,但我還沒有在 numpy 中看到避免它的方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.