【问题标题】:How do I fill an array according to distributions for each element in Python?如何根据 Python 中每个元素的分布填充数组?
【发布时间】:2021-01-11 18:46:17
【问题描述】:

假设我有 3 个盒子和 3 只动物,我想根据它们各自的分布创建一个包含 1 个动物的盒子数组:

animals = ["Cat", "Dog", "Bunny"]
boxes = []

概率由下式给出

       "Cat"   "Dog"   "Bunny"
Box 1   0.3     0.4     0.3    
Box 2   0.2     0.3     0.5
Box 3   0.5     0.3     0.2

我将如何填充框数组,使得第一个元素等于概率 0.3 的“猫”,概率 0.4 的“狗”和概率 0.3 的“兔子”,第二个元素等于“猫”概率为 0.2,“狗”的概率为 0.3 等等。

另外,假设第一个元素/框是“猫”。查看第二个和第三个盒子,我们不能有>0 的概率再次更改第一个盒子,因为它已经装满了一只猫。我们也不能让第二个盒子再次包含一只猫的概率 > 0,因为它已经在盒子 1 中。

是否可以通过将剩余的行/列缩放为 1 来负责任地解决这个问题,但它们的比例仍然相同?例如,如果框 1 是一只猫,那么我们会得到

       "Cat"   "Dog"   "Bunny"
Box 1   1       0       0    
Box 2   0       0.4     0.6
Box 3   0       0.6     0.4

【问题讨论】:

  • 如果一只猫在第一个盒子里,这是否意味着它不能在其他两个盒子里?另外,有没有可能装猫/狗/兔子的盒子?
  • @AliHassan 是的,每只动物只有 1 只,每个盒子只能同时放入 1 只。最后,所有盒子都必须装满 1 只动物。

标签: python arrays probability distribution


【解决方案1】:

您可以使用random.choices。它会自动加权选择:

boxes = []

animals = ["Cat", "Dog", "Bunny"]
box1 = [0.3, 0.4, 0.3]
box2 = [0.2, 0.3, 0.5]
# box3 = [0.5, 0.3, 0.2] is commented out because it can be ignored

# Choose the first item to go in box1
boxes.append(random.choices(animals, k = 1, weights = box1))
chosen_ind = animals.index(boxes[0])

# Remove the chosen item from animals and box2
animals.pop(chosen_ind)
box2.pop(chosen_ind)

# Choose the second item
boxes.append(random.choices(animals, k = 1, weights = box2))
chosen_ind = animals.index(boxes[1])

# Remove the chosen item from animals, append the only remaining item
animals.pop(chosen_ind)
boxes.append(animals[0])

我很清楚这不是解决问题的一种特别干净或可扩展的方法,但它可以为这种情况完成工作。

编辑:带有numpy数组的新版本是这样的

import numpy as np

boxes = []

# n animals to choose from
animals = ['cat', 'dog', 'bunny' ... ]   # as many items as needed

# n x n matrix of probabilities
prob = np.array([
    [prob(box1, cat), prob(box1, dog), ...]
    [prob(box2, cat), prob(box2, dog), ...]
    ...
])

for box_ind, box in enumerate(prob):
    boxes.append(random.choices(animals, k = 1, weights = box)
    col_ind = animals.index(boxes[box_ind])
    
    # This line sets the probability of a chosen item to 0 for future iterations
    prob[:, col_ind] = 0

【讨论】:

  • 感谢您的回答。为了扩大规模,是否可以创建一个盒子分布数组,然后迭代盒子[0]、盒子[1]等而不是盒子1、盒子2等?此外,这是否会在每次选择后自动重新调整概率?因为如果你删除比如说 cat 和 box 1,你最终会得到狗的重量 0.3 和兔子的 0.5,这会留下 0.2 的重量,什么都不会放——或者它会调整到 0.3 和 0.8 和 0.5权重不超过 0.8?
  • 它会自动调整。文档中发布的示例使用 10、45 等的权重,所以这没有问题。如果我要使其可扩展,我可能会考虑使用 numpy 数组,因为纯 python 可能对此效率不高
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-08-23
  • 2015-08-07
  • 2021-03-06
  • 1970-01-01
  • 1970-01-01
  • 2019-09-16
  • 2019-04-14
相关资源
最近更新 更多