将巨大的.data加载到数组中的最快方法

时间:2014-10-21 08:31:38

标签: python numpy bigdata

我在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

等等

由于

1 个答案:

答案 0 :(得分:3)

查看sourcenumpy.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编写的代码。我很想知道这些函数打开文件需要多长时间。