11

我想阅读一个包含整数列表列表的巨大文本文件。现在我正在执行以下操作:

G = []
with open("test.txt", 'r') as f:
    for line in f:
        G.append(list(map(int,line.split())))

但是,大约需要 17 秒(通过 timeit)。有什么办法可以减少这个时间吗?也许,有一种方法不使用地图。

4

6 回答 6

24

numpy 具有 和 的功能loadtxtgenfromtxt但都不是特别快。广泛分布的库中最快的文本阅读器之一是( http://pandas.pydata.org/ )中的read_csv函数。在我的电脑上,读取每行包含两个整数的 500 万行大约需要 46 秒,使用 26 秒,使用 1 秒多一点。pandasnumpy.loadtxtnumpy.genfromtxtpandas.read_csv

这是显示结果的会话。(这是在 Linux 上,Ubuntu 12.04 64 位。你在这里看不到它,但是在每次读取文件后,通过sync; echo 3 > /proc/sys/vm/drop_caches在单独的 shell 中运行来清除磁盘缓存。)

In [1]: import pandas as pd

In [2]: %timeit -n1 -r1 loadtxt('junk.dat')
1 loops, best of 1: 46.4 s per loop

In [3]: %timeit -n1 -r1 genfromtxt('junk.dat')
1 loops, best of 1: 26 s per loop

In [4]: %timeit -n1 -r1 pd.read_csv('junk.dat', sep=' ', header=None)
1 loops, best of 1: 1.12 s per loop
于 2013-02-26T19:26:07.700 回答
5

pandas它基于numpy有一个非常快的C基于文件解析器:

# generate some integer data (5 M rows, two cols) and write it to file
In [24]: data = np.random.randint(1000, size=(5 * 10**6, 2))

In [25]: np.savetxt('testfile.txt', data, delimiter=' ', fmt='%d')

# your way
In [26]: def your_way(filename):
   ...:     G = []
   ...:     with open(filename, 'r') as f:
   ...:         for line in f:
   ...:             G.append(list(map(int, line.split(','))))
   ...:     return G        
   ...: 

In [26]: %timeit your_way('testfile.txt', ' ')
1 loops, best of 3: 16.2 s per loop

In [27]: %timeit pd.read_csv('testfile.txt', delimiter=' ', dtype=int)
1 loops, best of 3: 1.57 s per loop

因此pandas.read_csv,读取您的数据大约需要 1.5 秒,并且比您的方法快 10 倍左右。

于 2013-02-26T19:46:51.490 回答
1

作为一般经验法则(几乎适用于任何语言),使用read()读取整个文件将比一次读取一行更快。如果您不受内存限制,请立即读取整个文件,然后在换行符上拆分数据,然后遍历行列表。

于 2013-02-26T18:28:49.573 回答
0

您也可以尝试通过批量插入将数据导入数据库,然后使用集合操作处理您的记录。根据您必须执行的操作,这可能会更快,因为批量插入软件已针对此类任务进行了优化。

于 2013-02-26T18:26:31.500 回答
0

最简单的加速是使用 PyPy http://pypy.org/

下一个根本不读取文件的问题(如果可能的话)。而是像流一样处理它。

于 2013-02-26T18:19:17.053 回答
0

列表推导通常更快。

G = [[int(item) item in line.split()] for line in f]

除此之外,试试 PyPy 和 Cython 和 numpy

于 2013-02-26T18:20:01.910 回答