Python 资源受限主机上的置换限制

Python 资源受限主机上的置换限制,python,algorithm,sed,shuffle,Python,Algorithm,Sed,Shuffle,我有一个大的文本文件,大约8GB,我需要随机地、均匀地移动它的行。我不能对文本文件进行分区,必须对整个文件进行洗牌 我遇到了GNUshuf在资源有限的主机(1GB内存)上浪费的限制,因此我正在探索有意保持在该主机能力范围内的替代方案 我的一个想法是从[1..n]构建一个Python(2.7.5)数字列表,其中n是这个8GB文件中的行数-大约2500万行-随机排列列表,并在列表上迭代以获得要馈送到sed-np的索引(或行号) Python排列2500万个元素列表的能力是否受到限制?当索引在该范围内

我有一个大的文本文件,大约8GB,我需要随机地、均匀地移动它的行。我不能对文本文件进行分区,必须对整个文件进行洗牌

我遇到了GNU
shuf
在资源有限的主机(1GB内存)上浪费的限制,因此我正在探索有意保持在该主机能力范围内的替代方案

我的一个想法是从
[1..n]
构建一个Python(2.7.5)数字列表,其中
n
是这个8GB文件中的行数-大约2500万行-随机排列列表,并在列表上迭代以获得要馈送到
sed-np
的索引(或行号)

Python排列2500万个元素列表的能力是否受到限制?当索引在该范围内时,
sed
s按索引有效拉出行的能力是否有限制


在资源有限的主机上,是否有更有效的方法来洗牌大文本文件行?

我认为下面的方法可能会奏效

from random import shuffle

# ... rest of the code ...

lnPos = [f.tell()]
for l in f.readlines(): lnPos.append( f.tell() )
shuffle( lnPos )

# Now open a file to write and write the lines
for pos in lnPos:
    f.seek(pos, 0)
    fOut.write( f.readline() )
我还没有检查语法错误,但我认为这可能行得通。让我知道进展如何。:)

这可能适合您(GNU-sed&sort):


在遍历文件的行时,可以将它们随机写入16个分区中的一个。然后,洗牌每个分区,然后重新加入它们

一些(未测试的)代码。该函数获取类文件对象in_file和out_file,以及要使用的分区数

def shuffle(in_file, out_file, n):
    out = [open('shard-%02d-of-%02d' % (i, n), 'w') for i in xrange(n)]
    for line in infile:
        out[random.randrange(n)].write(line)
    for o in out: o.close()
    for i in xrange(n):
        with open('shard-%02d-of-%02d' % (i, n), 'r') as part:
            lines = part.readlines()
        random.shuffle(lines)
        for x in lines:
            out_file.write(x)

基本上,它的想法是找到每行开头的位置,然后移动位置列表。位置列表有望比整个文件小得多。你正在阅读所有的行吗!?请注意,整个文件的大小为8 GB。我不完全确定
f.readlines()
函数的实际惰性。我也不确定我们如何在不读取行的情况下得到文件中行开头的位置列表。也许有一种更好/更有效的
find()
方法可以做同样的事情?其思想是找到文件中
\n
的位置,然后使用该信息对文件进行洗牌。您必须读取文件,才能知道行数。
readlines
创建文件中所有行的完整列表。这通常是不必要的<代码>对于f中的l以块而不是一次读取所有行,这就是您在这里想要的。我认为这不会在整个文件中均匀地排列。请注意,
sort-R
的结果不是真正的随机排列。@AlexReynolds您可以用
shuf
代替
sort-R
,因为您只处理25000000个整数。
def shuffle(in_file, out_file, n):
    out = [open('shard-%02d-of-%02d' % (i, n), 'w') for i in xrange(n)]
    for line in infile:
        out[random.randrange(n)].write(line)
    for o in out: o.close()
    for i in xrange(n):
        with open('shard-%02d-of-%02d' % (i, n), 'r') as part:
            lines = part.readlines()
        random.shuffle(lines)
        for x in lines:
            out_file.write(x)