我在stackexchange中广泛搜索了一个简洁的解决方案,用于将一个巨大的(~2GB).dat文件加载到一个numpy数组中,但是找不到合适的解决方案。到目前为止,我设法以非常快的方式将其加载为列表(<1分钟):
list=[]
f = open('myhugefile0')
for line in f:
list.append(line)
f.close()
使用np.loadtxt冻结我的计算机并需要几分钟才能加载(约10分钟)。如何在没有分配问题的情况下将文件作为数组打开,这似乎是瓶颈np.loadtxt?
编辑:
输入数据是一个float(200000,5181)数组。一行示例:
2.27069e-15 2.40985e-15 2.22525e-15 2.1138e-15 1.92038e-15 1.54218e-15 1.30739e-15 1.09205e-15 8.53416e-16 7.71566e-16 7.58353e-16 7.58362e- 16 8.81664e-16 1.09204e-15 1.27305e-15 1.58008e-15
等等
由于
答案 0 :(得分:3)
查看source,numpy.loadtxt
似乎包含许多处理许多不同格式的代码。如果您有一个定义良好的输入文件,那么编写针对您的特定文件格式优化的自己的函数并不困难。像这样(未经测试):
def load_big_file(fname):
'''only works for well-formed text file of space-separated doubles'''
rows = [] # unknown number of lines, so use list
with open(fname) as f:
for line in f:
line = [float(s) for s in line.split()]
rows.append(np.array(line, dtype = np.double))
return np.vstack(rows) # convert list of vectors to array
如果以前知道行数和列数,则替代解决方案可能是:
def load_known_size(fname, nrow, ncol)
x = np.empty((nrow, ncol), dtype = np.double)
with open(fname) as f:
for irow, line in enumerate(f):
for icol, s in enumerate(line.split()):
x[irow, icol] = float(s)
return x
通过这种方式,您不必分配所有中间列表。
编辑:似乎第二个解决方案有点慢,列表理解可能比显式for循环更快。结合这两个解决方案,并使用Numpy从字符串到float的隐式转换技巧(刚才发现),这可能会更快:
def load_known_size(fname, nrow, ncol)
x = np.empty((nrow, ncol), dtype = np.double)
with open(fname) as f:
for irow, line in enumerate(f):
x[irow, :] = line.split()
return x
要获得进一步的加速,你可能不得不使用一些用C或Cython编写的代码。我很想知道这些函数打开文件需要多长时间。