从列表中生成随机加权元组列表
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))
在这种情况下,我获取数组的随机索引。
有没有更优化的方式不用计算
概率数组?
还有一个问题就是prob数组和Counter数组不对应
如果您对计算频率的中间步骤不感兴趣,您可以使用 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次:
- 在
[0..n-1]
范围内随机选择一个数字 i
,其中 n
是 a
中的当前元素数。
- 在初始
a
列表的第 i
位置找到一个 tuple
。将 tuple
添加到生成的三元组中。
- 从
a
中删除所有出现的 tuple
。
注意 a
可以为空的极端情况。
列表的总体时间复杂度为 O(n)。
第一步数字i
应该根据正则random
提供的均匀分布生成。特定元组在 a
中出现的次数越多,它被选中的可能性就越大。
给定一个元组列表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))
在这种情况下,我获取数组的随机索引。
有没有更优化的方式不用计算 概率数组?
还有一个问题就是prob数组和Counter数组不对应
如果您对计算频率的中间步骤不感兴趣,您可以使用 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次:
- 在
[0..n-1]
范围内随机选择一个数字i
,其中n
是a
中的当前元素数。 - 在初始
a
列表的第i
位置找到一个tuple
。将tuple
添加到生成的三元组中。 - 从
a
中删除所有出现的tuple
。
注意 a
可以为空的极端情况。
列表的总体时间复杂度为 O(n)。
第一步数字i
应该根据正则random
提供的均匀分布生成。特定元组在 a
中出现的次数越多,它被选中的可能性就越大。