从文本文件中读取随机块
Read random chunks from text file
对于深度学习模型,我需要批量加载数据。对于每个时期(对所有数据进行完整迭代),每一行都需要传递一次,但重要的是数据以随机顺序提供给算法。我的数据集太大,无法在内存中完整读取。它是长度可变的序列数据,输入格式可以更改,因为它是我的其他脚本输出的集群的转储。目前它是每行的一些元信息,然后是按“;”分割的序列。
我目前的解决方案是一个生成器,它打乱所有行号,将它们分成 4 块并读取文件,解析与块行号匹配的行。它产生批量大小的序列,直到什么都没有,然后它解析下一个行号块。它有效,但我觉得可能有更好的解决方案。谁有更好的工作流程?这是我 运行 经常遇到的问题。问题是我正在完全扫描文件的每个块,每个时期。尽管我可以让它只用 4 个块工作,但 30 个 epoch 是读取一个大文件的 120 次。
在内存中建立行的索引(这需要单次遍历文件,但不是全部在内存中)然后你可以随机快速地访问行。
这不可靠(没有 validation/range-checking,等等)但是:
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
对于深度学习模型,我需要批量加载数据。对于每个时期(对所有数据进行完整迭代),每一行都需要传递一次,但重要的是数据以随机顺序提供给算法。我的数据集太大,无法在内存中完整读取。它是长度可变的序列数据,输入格式可以更改,因为它是我的其他脚本输出的集群的转储。目前它是每行的一些元信息,然后是按“;”分割的序列。
我目前的解决方案是一个生成器,它打乱所有行号,将它们分成 4 块并读取文件,解析与块行号匹配的行。它产生批量大小的序列,直到什么都没有,然后它解析下一个行号块。它有效,但我觉得可能有更好的解决方案。谁有更好的工作流程?这是我 运行 经常遇到的问题。问题是我正在完全扫描文件的每个块,每个时期。尽管我可以让它只用 4 个块工作,但 30 个 epoch 是读取一个大文件的 120 次。
在内存中建立行的索引(这需要单次遍历文件,但不是全部在内存中)然后你可以随机快速地访问行。
这不可靠(没有 validation/range-checking,等等)但是:
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