2012-11-12 4 views
1

모든 객체에는 "p"라는 객체 목록이 있습니다. 모든 객체에는 "a"가 있습니다 (예 : p [3] .a = 5). 나는 목록에서 임의의 객체를 선택하고자한다. 즉, 객체를 선택할 확률은 a의 값에 비례한다. 즉, a = 5 인 객체를 선택할 확률은 a = 1 인 객체를 선택할 확률의 5 배이다. . 어떻게하면 Python/Pylab/Numpy로 할 수 있습니까?Python - 목록에서 임의의 객체 선택

감사합니다.

답변

2

큰 계산에서는 효율적이지 않지만 정수 계산에는 작동합니다.

c = collections.Counter({k:k.a for k in stuff}) 
random.choice(list(c.elements())) 
+1

등가 Counter''없는 방법 :'random.choice (P에서 x의 [X를 (범위 내 (xa)에 대한)])' – agf

2

다음은보다 효율적인 방법입니다.

import random 

def weighted_choice(items): 
    # check if no items exist 
    if not items: 
     return None 

    # compute total of all weights 
    total = sum(item.weight for item in items) 

    # select a random point within the total 
    selection = random.randint(0, total - 1) 

    # find the corresponding item 
    count = 0 
    for item in items: 
     count += item.weight 
     if selection < count: 
      return item 
0

나는 당신이 한 번만 중단 점 목록을 구축해야 bisect

from bisect import bisect 

class Element(object): 
    def __init__(self, value): 
     self.a = value 
    def __repr__(self): 
     return 'Element({})'.format(self.a) 

data = [Element(3), Element(5), Element(7), Element(1)] 
last = 0 
breakpoints = [] 
for element in data: 
    breakpoints.append(last + element.a) 
    last += element.a 
print(breakpoints) 

for random_value in xrange(last): 
    pos = bisect(breakpoints, random_value) 
    print(random_value, data[pos]) 

사용하는 것이 좋습니다 것입니다. 그런 다음 당신이 원하는만큼 아주 빠른 이등분 알고리즘으로 사용할 수 있습니다.

마지막 루프는 결과를 보여주기위한 것입니다.

편집 : 브레이크 포인트를 얻을 수있는 다른 방법은 (나는에 대한 루프를 좋아하지 않았다) :

values = [value.a for value in data] 
breakpoints = [sum(values[:pos+1]) for pos in xrange(len(values))]