我想读一个包含整数列表列表的大文本文件。 现在我正在做以下事情:
G = []
with open("test.txt", 'r') as f:
for line in f:
G.append(list(map(int,line.split())))
然而,它需要大约17秒(通过时间)。有没有办法减少这个时间?也许,有一种方法不使用地图。
答案 0 :(得分:24)
numpy具有函数loadtxt
和genfromtxt
,但两者都不是特别快。广泛分布的库中最快的文本阅读器之一是read_csv
(http://pandas.pydata.org/)中的pandas
函数。在我的计算机上,每行读取包含两个整数的500万行,numpy.loadtxt
约为46秒,numpy.genfromtxt
约为26秒,pandas.read_csv
约为1秒。
这是显示结果的会话。 (这是在Linux上,Ubuntu 12.04 64位。你在这里看不到它,但在每次读取文件后,通过在一个单独的shell中运行sync; echo 3 > /proc/sys/vm/drop_caches
来清除磁盘缓存。)
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
答案 1 :(得分:5)
numpy
的 pandas
基于C
file parser非常快:
# 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
需要大约一秒半的时间来读取您的数据,并且比您的方法快10倍。
答案 2 :(得分:1)
作为一般经验法则(对于任何语言而言),使用read()
读取整个文件比一次读取一行更快。如果您不受内存约束,请立即读取整个文件,然后在换行符上拆分数据,然后遍历行列表。
答案 3 :(得分:0)
最简单的加速是去PyPy http://pypy.org/
下一个问题是根本不读取文件(如果可能的话)。而是像流一样处理它。
答案 4 :(得分:0)
列表理解通常更快。
G = [[int(item) item in line.split()] for line in f]
除此之外,尝试PyPy和Cython以及numpy
答案 5 :(得分:0)
您也可以尝试通过批量插入将数据导入数据库,然后使用set操作处理记录。根据您的操作,可能会更快,因为批量插入软件针对此类任务进行了优化。