Skip to main content
 首页 » 编程设计

python之如何在不生成范围(n)的情况下对具有 n 个条目的数组进行洗牌

2025年05月04日8mq0036

所以,我在看 python,我有一个大的 2d numpy 数据数组,我想获取这个大数据矩阵的 m 行。我研究了 random.sample、numpy.random.shuffle 和 numpy.random.permutation,所有这些都有效,但通常它们会返回整个排列或至少生成整个范围 (n)。如果我有一个非常大的数据集,然后做类似的事情

 data = numpy.random.uniform((n,100)) 
 myvec = data[random.sample(range(n),m),:] 

将分配一个向量范围(n),它会很快爆炸。所以我想我可以使用 xrange,它返回一个生成器,但是嘿,你不能只从生成器中获取任何元素,这不是它们的工作方式。

我试过了,效果不错。

 data = numpy.random.uniform((n,100)) 
 myvec = data[random.sample(xrange(n),m),:] 

知道怎么做吗?

更新:

我可以用

 samp = random.sample(range(n),10) 

在出现内存错误之前,最多 n 100000000。如果我使用

 samp = random.sample(xrange(n),10) 

另一方面,我只是因为 int converson to C 才开始出现错误,也就是说,int 变得太长而无法转换为 C,大约为 1000000000。当然这只是 10 的一个因数,但我很好奇. xrange 变体也快得多。

请您参考如下方法:

def sample(n, m): 
    d = set() 
    while len(d) < m: 
        d.add(randrange(n)) 
    return d 
 
>>> sample(100000000000000000000000000000000000, 10) 
set([5577049102993258248888250482046894L, 86044086231860190654588187118815513L, 2021737354726858669049814270580972L, 6253501639432326715043836478191628L, 5306460388221333758367322518700483L, 62195356583363524099133566314034473L, 376650426515181012918370326724858L, 80588135672357701239461833469588557L, 1978959860575617450893346333245569L, 41904683348442252013350548717573039L]) 

请注意,简单的 {randrange(n) for _ in range(m)} 将以非常高的概率完成这项工作。