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

时间:2014-02-15 01:14:06

标签: python algorithm sed shuffle

我有一个大的文本文件,大约8 GB,我的行需要随机和均匀地随机播放。我无法对文本文件进行分区和随机播放 - 必须在整个文件上进行随机播放。

我遇到了GNU shuf在资源有限的主机(1 GB内存)上崩溃的限制,所以我正在探索故意留在这个主机能力范围内的替代方案。

我有一个想法是从[1..n]构建一个Python(2.7.5)数字列表,其中n是这个8 GB文件中的行数 - 大约2500万行 - 随机置换列表,并遍历列表以获取要提供给sed -n <line_index>p的索引(或行号)。

Python是否有能力置换25M元素列表? sed是否有能力通过索引有效地提取线,其中指数是该范围的?

是否有更有效的方法在资源受限的主机上重排大型文本文件?

3 个答案:

答案 0 :(得分:3)

我认为以下内容可能有用。

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() )

我没有检查过语法错误,但我认为这可能会起作用。让我知道事情的后续。 :)

答案 1 :(得分:0)

这可能适合你(GNU sed&amp; sort):

seq $(cat file | wc -l) | sort -R | sed 's|.*|sed -n '\''&{p;q}'\'' file|e' >output

答案 2 :(得分:0)

当您遍历文件行时,可以将它们随机写入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)