从列表中生成随机加权元组列表

Generate a list of random weighted tuples from a list

给定一个元组列表a:

a =[(23, 11), (10, 16), (13, 11),  (12, 3), (4, 15), (10, 16), (10, 16)]

我们可以使用 Counter:

来计算每个元组出现了多少次
>>> from collections import Counter
>>> b = Counter(a)
>>> b
Counter({(4, 15): 1, (10, 16): 3, (12, 3): 1, (13, 11): 1, (23, 11): 1}

现在,想法是从列表中select 3 个随机元组,不重复,这样计数决定了选择特定元组的概率。

例如,(10, 16) 比其他元组更有可能被选中 - 它的权重为 3/7,而其他四个元组的权重为 1/7。

我试过使用np.random.choice:

a[np.random.choice(len(a), 3, p=b/len(a))]

但我无法生成元组。

我正在尝试:

a =[(23, 11), (10, 16), (13, 11),  (10, 16), (10, 16), (10, 16), (10, 16)]
b = Counter(a)
c = []
print "counter list"
print b
for item in b:
    print "item from current list"
    print item
    print "prob of the item"
    print (float(b[item])/float(len(a)))

    c.append(float(b[item])/float(len(a)))

print "prob list"
print c

print (np.random.choice(np.arange(len(b)), 3, p=c, replace=False))

在这种情况下,我获取数组的随机索引。

如果您对计算频率的中间步骤不感兴趣,您可以使用 random.shuffle(在列表或副本上),然后根据需要切掉尽可能多的项目。

例如

import random
a =[(23, 11), (10, 16), (13, 11),  (12, 3), (4, 15), (10, 16), (10, 16)]
random.shuffle(a)
random_sample = a[0:3]
print(random_sample)

由于随机重新排序,它将避免重复问题,并且统计上应该给出相同的结果(不包括 np 和 random 之间随机数生成的差异)。

这样就可以了

from collections import Counter
import matplotlib.pyplot as plt
import numpy as np
import random

listOfNumbers =[(23, 11), (10, 16), (13, 11),  (10, 16), (10, 16), (10, 16), (10, 16)]
b = Counter(listOfNumbers)
c = []
pres=[]
for k,v in b.most_common():
    c.append(float(v)/float(len(listOfNumbers)))
    pres.append(k)

resultIndex = np.random.choice(np.arange(len(b)), 3, p=c, replace=False)

ass=[]
for res in resultIndex:
    ass.append(pres[res])

print ass

现在就是看看有没有办法优化一下

您可以重复以下步骤3次:

  1. [0..n-1] 范围内随机选择一个数字 i,其中 na 中的当前元素数。
  2. 在初始 a 列表的第 i 位置找到一个 tuple。将 tuple 添加到生成的三元组中。
  3. a 中删除所有出现的 tuple

注意 a 可以为空的极端情况。

列表的总体时间复杂度为 O(n)

第一步数字i应该根据正则random提供的均匀分布生成。特定元组在 a 中出现的次数越多,它被选中的可能性就越大。