Python问题。我正在生成大量的对象,我只需要做一个小的随机样本。实际上生成有问题的对象需要一段时间,所以我想知道是否有可能以某种方式跳过那些不需要生成的对象,只显式创建那些已经采样的对象。
换句话说,我现在有
a = createHugeArray()
s = random.sample(a,len(a)*0.001)
这是相当浪费的。我更喜欢像懒惰的东西
a = createArrayGenerator()
s = random.sample(a,len(a)*0.001)
我不知道这是否有效。 random.sample上的文档不太清楚,虽然它提到xrange非常快 - 这让我相信它可能会起作用。将数组创建转换为生成器将是一项工作(我对生成器的了解非常生疏),所以我想知道这是否有效。 :)
我可以看到的替代方法是通过xrange制作随机样本,并仅生成那些通过索引实际选择的对象。虽然这不是很干净,因为生成的索引是任意的和不必要的,我需要相当hacky逻辑来支持我的generateHugeArray方法。
对于奖励积分:random.sample实际上如何运作?特别是,如果像xrange这样的生成器不提前知道人口的大小,它是如何工作的?
答案 0 :(得分:2)
似乎没有办法避免弄清楚索引如何映射到你的排列。如果您不知道这一点,您将如何从数组中创建一个随机对象?您可以使用自己建议的xrange()
来使用该技巧,或者实现一个定义__getitem__()
和__len__()
方法的类,并将此类的传递和对象作为population
参数传递给{ {1}}。
进一步评论:
将createHugeArray()转换为生成器不会为您带来任何好处 - random.sample()
将不再适用。它需要一个支持random.sample()
的对象。
所以确实需要从一开始就知道人口中元素的数量。
implementation具有两种不同的算法,并选择使用较少内存的算法。对于相对较小的len()
(即,在手头的情况下),它将简单地保存已在k
中选择的索引,并且如果它击中其中一个,则进行新的随机选择。
编辑:完全不同的方法是迭代所有排列一次,并决定是否应该包括每个排列。如果排列总数为set
,并且您想要选择n
,则可以写
k
这会随机选择selected = []
for i in xrange(n):
perm = nextPermutation()
if random.random() < float(k-len(selected))/(n-i):
selected.append(perm)
个排列。
答案 1 :(得分:0)
您可以使用sample创建数组索引列表,然后根据结果生成对象:
def get_object(index):
return MyClass(index)
或类似的东西。然后使用sample生成所需的索引,并使用这些索引调用此函数:
objs = map(get_object, random.sample(range(length), 0.001 * length))
这有点间接,因为它只从可能的数组索引列表中选择。
答案 2 :(得分:0)
解释random.sample的工作原理,
random.sample(container, k)
将从容器中随机返回k个值。因为生成器可以像列表,元组和dicts中的键或值一样进行迭代,它将遍历容器然后获取这些随机元素。
e.g。 random.sample(xrange(111),4)
将返回[33,52,111,1]
之类的k = 4
,意味着xrange生成器中的4个随机数,最多为111个。
答案 3 :(得分:0)
我猜测函数createHugeArray()包含一段代码,对于每个创建的对象重复一次。而且我猜测对象是从某种初始值或种子生成的,在这种情况下createHugeArray()看起来像这样:
def createHugeArray( list_of_seeds ):
huge_array = []
for i in list_of_seeds:
my_object = makeObject( i )
huge_array.append( my_object )
return huge_array
(我使用的列表不是数组,但你明白了。)
要在实际创建对象之前进行随机抽样,只需添加一条生成随机数的行,然后仅在随机数低于某个阈值时才创建对象。假设你只需要一千个物体。 random.randint(0,999)给出一个从0到999的数字 - 所以只有在你得到零时才生成一个对象。上面的代码变为:
import random
def createHugeArray( list_of_seeds ):
huge_array = []
for i in list_of_seeds:
die_roll = random.randint(0,999)
if( die_roll == 0 ):
my_object = makeObject( i )
huge_array.append( my_object )
return huge_array
当然,如果我猜测你的代码是如何工作的,那么这对你来说是没用的,在这种情况下抱歉和好运: - )