Python 如何对几个具有不同分布的数字进行采样?

Python 如何对几个具有不同分布的数字进行采样?,python,numpy,random,scipy,Python,Numpy,Random,Scipy,假设我有自己的自定义分布numpy向量,名为p 然后p满足以下条件: np.ndim(p) == 1 & np.sum(p) == 1 & np.all(p >= 0) 有了这个向量,我可以很容易地用np.random.choice(np.arange(len(p)),p=p)对[0,p.shape]中的一个数字进行采样 在一个例子中,我有许多这样的ps,我有一个矩阵(带dim 2)p,它满足: np.sum(P[:,i]) == 1 # for all i in P

假设我有自己的自定义分布numpy向量,名为
p

然后
p
满足以下条件:

np.ndim(p) == 1 & np.sum(p) == 1 & np.all(p >= 0)
有了这个向量,我可以很容易地用
np.random.choice(np.arange(len(p)),p=p)对
[0,p.shape]
中的一个数字进行采样

在一个例子中,我有许多这样的
p
s,我有一个矩阵(带dim 2)
p
,它满足:

np.sum(P[:,i]) == 1   # for all i in P.shape[1]
np.all(P >= 0)
然后我想用概率p对0到
p.shape[0]
范围内的
p.shape[1]
数字进行采样

例如,下一个代码:

P = np.array([[0.2, 0.3],
              [0.5, 0.7],
              [0.3, 0]])
x = np.random.choice(np.arange(P.shape[0], P[:,0]))
y = np.random.choice(np.arange(P.shape[0], P[:,1]))
将产生我的遗嘱(
x=0
in
0.2
x=1
in
0.5
x=2
in
0.3
y=0
in
0.3
y=1
in
0.7

在我的例子中,
p
有许多列,我希望在一次拍摄中对所有列进行采样

当然,我可以在for循环中完成,例如:

random_values = np.empty(P.shape[1])
arange_arr = np.arange(P.shape[0])
for i in range(P.shape[1]):
    random_values[i] = np.random.choice(arange_arr, p=P[:,i])

试着找到一些简单优雅的方法来做这件事。

你可以这样做:

P = np.array([[0.2, 0.3],
              [0.5, 0.7],
              [0.3, 0]])
P_upper = np.cumsum(P, axis=0)
P_lower = np.concatenate((np.zeros((1, P.shape[1])), P_upper[:-1, :]), axis=0)
这将创建一组可以数字化的箱子。现在生成0到1之间的随机数:

r = np.random.rand(10, P.shape[1])
有几种方法可以将数据分配到正确的存储箱。快速且相对低效的方法是使用布尔掩码:

mask = (r[None, ...] >= P_lower[:, None, :]) & (r[None, ...] < P_upper[:, None, :])
result = np.argmax(mask, axis=0)
TL;DR

def multi_sample(p, n):
    ps = np.cumsum(p, axis=0)
    r = np.random.rand(n, ps.shape[1])
    offset = np.arange(P.shape[1])
    ind = np.searchsorted((P_upper + offset).ravel('F'), (r + offset).ravel('F')).reshape(r.shape, order='F')
    return ind - offset * P.shape[0]

太长了,读不下去了。谢谢你,我希望在MUYY/SCIPY……= @ @沙克中有一些内置函数。你可以自己制作实用程序。这不应该是个问题。我会添加TL;DRthanks。我想TL;DR可能在答案开始时更好,不是吗?@沙克。因为它代表“太长了,没读过”。,我相信习惯上会把它放在最后,在那里你可以滚动到它经过主帖子。另外,向上投票也很好。
def multi_sample(p, n):
    ps = np.cumsum(p, axis=0)
    r = np.random.rand(n, ps.shape[1])
    offset = np.arange(P.shape[1])
    ind = np.searchsorted((P_upper + offset).ravel('F'), (r + offset).ravel('F')).reshape(r.shape, order='F')
    return ind - offset * P.shape[0]