在Python中读取具有不同数量列的大型文件的最快方法

时间:2017-09-20 19:17:34

标签: python file pandas numpy

我在文件data.txt中有一个浮点数的数据集,每行包含可变数量的列。例如:

    3.0 2.5
    1.1 30.2 11.5
    5.0 6.2
    12.2 70.2 14.7 3.2 1.1

为了阅读它,我可以轻松地在Matlab中使用fopenfscanf的组合。最后一个按列顺序读取数据并将其转换为数组,如下所示:

    array = [3.0 2.5 1.1 30.2 11.5 5.0 6.2 12.2 70.2 14.7 3.2 1.1]'

我想将我的Matlab代码翻译成Python。但由于没有Python内置函数替换Matlab的fscanf,我编写了以下Python代码,以与描述相同的方式读取和重塑数据:

    from numpy import *

    data = []
    with open('data.txt') as file:
       for line in file:
          cline = line.split()
          data = data + cline

    data = array(data)

这样可行,但我的一些数据集最多可以包含200,000行,而我所显示的Python代码对于大数据集的读取速度非常慢(大约10分钟)。另一方面,Matlab的fscanf只需几秒钟或更短的时间完成工作。那么,有没有比我的代码更快(优化)的方法在Python中执行此操作?

我真的很感激任何建议。

3 个答案:

答案 0 :(得分:2)

在几千行之后,这需要做大量的额外工作:

this.saveAs(fileName);

只需 data = data + cline 。 (或data.extend(cline),如果你想知道哪一个数字一起出现在一条线上。)

考虑存储双打而不是文本:

.append()

答案 1 :(得分:2)

numpy.loadtxt在这里完美无法应用,因为列数会发生变化。

你想要一个平面列表,你可以通过使用列表理解来加快它的速度:

from numpy import *
with open("file.txt") as f:
    data = array([float(x) for l in f for x in l.split()])

(现在我很确定考虑到JH在他的回答中指出的错误会更快:data = data + line每次创建一个新列表:二次复杂性。你可以通过列表补偿来避免这种情况)

答案 2 :(得分:2)

Pandas处理乱七八糟的列比numpy更好/更快,并且应该比带循环的vanilla python实现更快。

使用read_csv,然后使用stack,然后访问values属性以返回numpy数组。

max_per_row = 10 # set this to the max possible number of elements in a row

vals = pd.read_csv(buf, header=None, names=range(max_per_row),
                             delim_whitespace=True).stack().values

print(vals)
array([  3. ,   2.5,   1.1,  30.2,  11.5,   5. ,   6.2,  12.2,  70.2,
        14.7,   3.2,   1.1])