来自.txt文件的NumPy数组太大,无法加载到内存中



我有一个大约6Gb的大。txt文件,结构如下:

0.1 0.4 0.9 1.2 0.2 3.8
2.8 4.2 0.3 1.9
0.3 5.8 9.6 0.05 2.2

我将其转换为NumPy数组并使用.loadtxt(file.txt)获得:

[[0.1 0.4 0.9 1.2 0.2 3.8], [2.8 4.2 0.3 1.9], [0.3 5.8 9.6 0.05 2.2]]

这个文件现在太大了,无法加载到内存中,我得到了一个内存错误,所以我一直在尝试用这个

来加载它。
def loadFile(filePath):
chunk_size = 10000
data = []
with open(filePath, 'r') as f:
while True:
chunk = np.genfromtxt(f, max_rows=chunk_size)
if len(chunk) < chunk_size:
# Last chunk 
data.append(chunk)
break 
data.append(chunk)
# Move pointer to start of next chunk
f.seek(chunk_size-len(chunk), 1)
# Joining chunks into a single array
data = np.concatenate(data)
return data

我认为我只需要一次加载一个块到内存中,但这仍然会使我的RAM最大化,并使我的PC崩溃。

我错过了什么?将文件分割成多个文件确实不是一个选项。

当您使用chunking来分解一个大数据文件时,您应该将load数据块放入内存,process它,然后free内存。您在代码中所做的是chunking数据,将其添加到data数组中,然后将concatenating块添加到单个数组中。这是的等效一次加载整个数据文件除了额外的步骤。如果需要整个数据集来进行处理,则可能需要升级硬件或寻找替代模块。但是,如果您不需要使用整个数据集,您可以在读取块的while循环中进行处理:

with open(filePath, 'r') as f:
while True:
chunk = np.genfromtxt(f, max_rows=chunk_size)
if len(chunk) < chunk_size:
# Last chunk 
data.append(chunk)
break 
#Do some processing here
[insert code]
# Move pointer to start of next chunk
f.seek(chunk_size-len(chunk), 1)

如果可能的话,您可以尝试指定较小的数据类型。单靠它可能解决不了问题,但应该有所帮助。

Python的float值通常是64位的,接近C的double。在Numpy中,您可以使用numpy.single(32位)或numpy.half(16位)。
要指定数据类型,必须将dtype作为参数传递给loadtxt。例如:

data = np.loadtxt(fileName, dtype=np.half)

参考资料(来自Numpy的文档):

  • loadtxt: https://numpy.org/doc/stable/reference/generated/numpy.loadtxt.html
  • NumPy的数据类型:https://numpy.org/doc/stable/user/basics.types.html