在文件中提取随机行而不将文件加载到python中的RAM中

时间:2014-03-02 17:00:35

标签: python file svmlight

我有大的svmlight文件,我正在用于机器学习目的。我试图看看这些文件的总和是否会导致足够好的结果。

我想提取我的文件的随机行以将它们提供给我的模型,但我想在RAM中加载较少的信息。

我在这里看到(Read a number of random lines from a file in Python)我可以使用linecache,但所有解决方案最终都会将所有内容加载到内存中。

有人可以给我一些提示吗?谢谢。

编辑:忘了说我事先知道我文件中的行数。

3 个答案:

答案 0 :(得分:5)

您可以使用heapq根据随机数选择 n 记录,例如:

import heapq
import random

SIZE = 10
with open('yourfile') as fin:
    sample = heapq.nlargest(SIZE, fin, key=lambda L: random.random())

这非常有效,因为heapq保持固定大小,它不需要预先扫描数据,并且元素会被换出,因为其他元素被选中 - 所以最多你最终会得到{{1一次在内存中的元素。

答案 1 :(得分:3)

一种选择是对文件进行随机搜索,然后在读取行之前向后查找换行符(或文件的开头)。这是一个程序,它打印在当前目录中找到的每个Python程序的随机行。

import random
import os
import glob

for name in glob.glob("*.py"):
    mode, ino, den, nlink, uid, gid, size, atime,  mtime, ctime = os.stat(name)
    inf = open(name, "r")
    location = random.randint(0, size)
    inf.seek(location)
    while location > 0:
        char = inf.read(1)
        if char == "\n":
            break
        location -= 1
        inf.seek(location)
    line = inf.readline()
    print name, ":", line[:-1]

只要线条不大,就不应该过度繁重。

答案 2 :(得分:1)

您可以扫描文件一次,计算行数。一旦你知道了,你可以生成随机行号,重新读取文件并在看到它时发出该行。

实际上,由于您对多行感兴趣,因此您应该查看Efficiently selecting a set of random elements from a linked list