Python 使用SciPy/NumPy在有限概率权重上循环

Python 使用SciPy/NumPy在有限概率权重上循环,python,python-3.x,numpy,scipy,probability,Python,Python 3.x,Numpy,Scipy,Probability,让我们有一个单事件概率prob,它是一个介于0-1之间的标量。如果我想以0.1的增量迭代所有可能的概率,那么我可以使用: prob = np.arange(0.01, 1, 0.1) 现在假设我有5个事件(独立,概率总和为1),每个事件的概率pi。我想要多维概率数组,例如: 1.0 - 0.0 - 0.0 - 0.0 - 0.0 0.9 - 0.1 - 0.0 - 0.0 - 0.0 0.9 - 0.0 - 0.1 - 0.0 - 0.0 0.9 - 0.0 - 0.0 - 0.1 - 0.0

让我们有一个单事件概率
prob
,它是一个介于0-1之间的标量。如果我想以0.1的增量迭代所有可能的概率,那么我可以使用:

prob = np.arange(0.01, 1, 0.1)
现在假设我有5个事件(独立,概率总和为1),每个事件的概率
pi
。我想要多维概率数组,例如:

1.0 - 0.0 - 0.0 - 0.0 - 0.0
0.9 - 0.1 - 0.0 - 0.0 - 0.0
0.9 - 0.0 - 0.1 - 0.0 - 0.0
0.9 - 0.0 - 0.0 - 0.1 - 0.0
0.9 - 0.0 - 0.0 - 0.0 - 0.1
0.8 - 0.1 - 0.1 - 0.0 - 0.0
0.8 - 0.1 - 0.0 - 0.1 - 0.0
.      .     .     .     .
.      .     .     .     .
.      .     .     .     . 
0.2 - 0.2 - 0.2 - 0.2 - 0.2

有没有比考虑0—0.1……的所有组合更聪明的方法?1并删除总和不等于1的行?如果是,最简单的方法是什么?

可能有一个更优雅的解决方案使用itertools,但这可能很好,并且不使用依赖项:

for i in prob:
  for j in prob:
     for k in prob:
        for l in prob:
           m = 1 - i - j - l
           if m>=0:
              print(i,j,k,l,m)

可能有一个更优雅的解决方案使用itertools,但这可能很好,并且不使用依赖项:

for i in prob:
  for j in prob:
     for k in prob:
        for l in prob:
           m = 1 - i - j - l
           if m>=0:
              print(i,j,k,l,m)

您可以使用
itertools.product
filter
创建求和10的所有组合并将其传递给数组:

import itertools
f = filter(lambda x: sum(x) == 10, itertools.product(*[range(11)]*5))
x = np.array(list(f)).astype(np.float)/10
x
>> array([[0. , 0. , 0. , 0. , 1. ],
       [0. , 0. , 0. , 0.1, 0.9],
       [0. , 0. , 0. , 0.2, 0.8],
       ...,
       [0.9, 0. , 0.1, 0. , 0. ],
       [0.9, 0.1, 0. , 0. , 0. ],
       [1. , 0. , 0. , 0. , 0. ]])
编辑

为了记录在案,这里有一种不使用过滤的更有效的方法。基本上,您创建了
k
bin(在您的示例中为10个),并在所有可能的组合中,使用
compositions\u和\u replacement将它们“分配”给“n”个样本(在您的示例中为3个)

然后,计算每个样本得到的垃圾箱数量:这是您的概率。这种方法理解起来更复杂,但避免了
过滤器
,因此效率更高。您可以尝试使用0.01的除法(
k=100


您可以使用
itertools.product
filter
创建求和10的所有组合并将其传递给数组:

import itertools
f = filter(lambda x: sum(x) == 10, itertools.product(*[range(11)]*5))
x = np.array(list(f)).astype(np.float)/10
x
>> array([[0. , 0. , 0. , 0. , 1. ],
       [0. , 0. , 0. , 0.1, 0.9],
       [0. , 0. , 0. , 0.2, 0.8],
       ...,
       [0.9, 0. , 0.1, 0. , 0. ],
       [0.9, 0.1, 0. , 0. , 0. ],
       [1. , 0. , 0. , 0. , 0. ]])
编辑

为了记录在案,这里有一种不使用过滤的更有效的方法。基本上,您创建了
k
bin(在您的示例中为10个),并在所有可能的组合中,使用
compositions\u和\u replacement将它们“分配”给“n”个样本(在您的示例中为3个)

然后,计算每个样本得到的垃圾箱数量:这是您的概率。这种方法理解起来更复杂,但避免了
过滤器
,因此效率更高。您可以尝试使用0.01的除法(
k=100


它应该是np.arange(0,1.1,0.1)吗?只是澄清一下,你想生成概率矩阵吗?或者你已经有了它,想要删除不等于1的行?@DavidKong我想自己安排这些边界。“我不希望概率为零,也不希望1-0=1。”布伦拉谢谢你的提问。我想生成这个概率矩阵。它应该是np.arange(0,1.1,0.1)吗?只是澄清一下,你想生成概率矩阵吗?或者你已经有了它,想要删除不等于1的行?@DavidKong我想自己安排这些边界。“我不希望概率为零,也不希望1-0=1。”布伦拉谢谢你的提问。我想生成这个prob矩阵。你认为将断点设置为0.01容易吗?是的,只需将
range(11)
替换为
range(101)
sum(x)=10
替换为
sum(x)=100
,将
/10
替换为
/100
。警告你,这是一个巨大的矩阵!这只是出于好奇,我没有足够的勇气来运行:)我也很好奇,因为我知道必须有一种方法来避免创建所有组合并过滤它们(我想我找到了)。你认为把断点设置为0.01容易吗?是的,用
range(101)
替换
range(11)
sum(x)==10
替换
sum(x)==100
,用
/100
替换
/10
。警告你,这是一个巨大的矩阵!这只是出于好奇,我没有足够的勇气来运行:)我也很好奇,因为我知道必须有一种方法来避免创建所有组合并过滤它们(我想我找到了)。我把它添加到了答案中。