Python不是从对象列表中随机抽样

我有大约20,000个对象的字典键是对象的字符串表示,值是对象本身.每个对象都有self.length和self.rate属性. self.rate计算为1.5E-8 * self.length.

我需要根据它们的速率选择一个预先确定的数字(我们假设这个例子是500)这个项目中的项目.具有较低速率的对象将不太可能被选择并且具有较高速率的对象更可能被选择.

我认为我能做到这一点的方式非常缓慢.

在while循环中,当所选对象的数量小于所需选择的数量时,我生成一个介于0之间的随机数和dict的长度并选择该元素.然后我生成另一个随机数,如果随机数小于列表中所选对象的速率,则会将其添加到所选对象中.这开始似乎很好,但现在我意识到它太慢了.有没有人有关于如何更快地做到这一点的建议?

一些代码:
对象的类定义

from numpy import random
class object():
    def __init__(self, length):
        self.length  = length
        self.rate = (1.15E-8*self.length)

    def select(self):
        x = random.uniform(0,1)
        if(x<self.rate):
            return True
        else:
            return False

剩下的功能(在另一个模块中):

def select_random(object_dict,maxselect):
    nselect = 0
    object_names = object_dict.keys()
    selected_objects = []
    while(nselect < maxselect):
        x = random.randint(0,len(object_dict))
        if(object_dict[object_names[x]].select()):
            nselect +=1
            selected_objects.append(object_names[x])
    return(selected_objects)

我认为让它变得非常慢的原因是每个对象被选中的概率非常小,甚至在选择一个对象之前需要进行多次迭代,更不用说500或更多.

长度分布:

Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
     51     822    1311    1770    2112  103000 

最佳答案 试试这个:

import numpy as np    # requires NumPy 1.7 (!)

def select_random(object_dict, n):
    keys = object_dict.keys()
    rate = np.array([x.rate for x in keys])
    prob = rate / rate.sum()
    return np.random.choice(keys, size=n, replace=True, p=prob)

(Documentation)

P.S.,调用类对象是个坏主意,因为它也是内置通用基类的名称.

点赞