从文本文件中读取随机块

时间:2016-08-12 12:40:44

标签: python out-of-memory deep-learning

对于深度学习模型,我需要批量加载数据。对于每个时期(对所有数据的完全迭代),每行需要传递一次,但重要的是数据以随机顺序馈送到算法。我的数据集太大,无法在内存中完全读取。它是具有可变长度的序列数据,输入格式可以更改,因为它是来自我的其他脚本输出的集群的转储。目前,每行有一些元信息,然后用';'分割序列。

我目前的解决方案是一个生成器,它将所有行号混洗,将它们分成4块并读取文件,解析与块行号匹配的行。它产生批量大小的序列,直到没有任何东西,然后它解析下一个行号。它有效,但我觉得可能有更好的解决方案。谁有更好的工作流程?这是我经常遇到的问题。问题是我正在为每个时间段的每个块完全扫描文件。即使我只能使用4个块来处理它,但有30个时期可以读取120个大文件。

1 个答案:

答案 0 :(得分:3)

在内存中构建行的索引(需要单个遍历文件,但不能全部在内存中),然后您可以随机快速地访问行。

这不健全(没有验证/范围检查等),但是:

import sys

BUFFER_LEN = 1024


def findNewLines(s):
   retval = []
   lastPos = 0
   while True:
      pos = s.find("\n", lastPos)
      if pos >= 0:
         pos += 1
         retval.append(pos)
         lastPos = pos
      else:
         break
   return retval


class RandomAccessFile(object):
   def __init__(self, fileName):
      self.fileName = fileName
      self.startPositions = [0]
      with open(fileName, "rb") as f:
         looking = True
         fileOffset = 0
         while (looking):
            bytes = f.read(BUFFER_LEN)
            if len(bytes) < BUFFER_LEN:
               looking = False
            newLines = findNewLines(bytes)
            for newLine in newLines:
               self.startPositions.append(fileOffset+newLine)
            fileOffset += len(bytes)

   def GetLine(self, index):
      start, stop = self.startPositions[index],self.startPositions[index+1]-1
      with open(self.fileName, "rb") as f:
         f.seek(start)
         return f.read((stop-start)-1)



raf = RandomAccessFile('/usr/share/dict/words')


print raf.GetLine(0)
print raf.GetLine(10)
print raf.GetLine(456)
print raf.GetLine(71015)

输出是:

python indexedFile.py
A
Aaronic 
abrim 
flippantness