我想讀取包含整數列表的大文本文件。 現在我做的是以下幾點:在Python中讀取輸入的最快方法
G = []
with open("test.txt", 'r') as f:
for line in f:
G.append(list(map(int,line.split())))
但是,它需要大約17秒(通過timeit)。有什麼辦法可以縮短這個時間嗎?也許,有一種不使用地圖的方法。
我想讀取包含整數列表的大文本文件。 現在我做的是以下幾點:在Python中讀取輸入的最快方法
G = []
with open("test.txt", 'r') as f:
for line in f:
G.append(list(map(int,line.split())))
但是,它需要大約17秒(通過timeit)。有什麼辦法可以縮短這個時間嗎?也許,有一種不使用地圖的方法。
最簡單的加速會去PyPy http://pypy.org/
下一個問題不能讀取所有文件(如果可能)。而是像流一樣處理它。
列表解析速度通常更快。
G = [[int(item) item in line.split()] for line in f]
除此之外,嘗試PyPy以及用Cython與numpy的
'G = [map(int,line.split())for line in f]'更快。 – 2013-02-26 18:41:38
@StevenRumbalski這條線產生地圖對象:'[<0x0000000002D28898>處的地圖對象,<0x0000000002D28908>處的地圖對象,<0x0000000002D289B0> ...處的地圖對象'。但@forivall行可以工作。 – 2013-02-26 18:54:26
@BranAlgue。啊哈!你正在使用Python 3.所以把它改成'G = [list(map(int,line.split()))for line in f]'。它仍然比嵌套列表理解更快。 – 2013-02-26 19:01:06
您還可以嘗試通過批量插入帶來的數據到數據庫中,然後用一組操作處理您的記錄。取決於您必須做什麼,這可能會更快,因爲批量插入軟件已針對此類任務進行了優化。
作爲一般的經驗法則(幾乎任何語言),使用read()
來讀取整個文件將比讀取一行更快。如果您不受內存限制,請立即讀取整個文件,然後在新行上拆分數據,然後迭代行列表。
numpy具有功能loadtxt
和genfromtxt
,但都不是特別快。在廣泛分佈的庫中可用的最快速的文本閱讀器之一是read_csv
函數pandas
(http://pandas.pydata.org/)。在我的計算機上,每行讀取500萬行,每行包含兩個整數需要46秒,其中numpy.loadtxt
,22637秒,numpy.genfromtxt
,以及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,在我準備我的時候沒有看到你的答案。我只是對OP的版本進行了基準測試,在我的機器上需要大約16秒。我還注意到,'loadtxt'很慢。我不知道爲什麼,我預計它會更快(它應該比'genfromtxt'更快。你還使用numpy 1.7嗎? – bmu 2013-02-26 20:03:37
@bmu:是的,我用numpy 1.7。 – 2013-02-26 20:05:07
我打開了一個numpy問題: https://github.com/numpy/numpy/issues/3019。我無法想象,'loadtxt'太慢是很正常的。 – bmu 2013-02-26 20:16:26
pandas
這基於numpy
有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倍左右。
嘗試列表理解。 – 2013-02-26 18:17:47
有沒有理由不在這裏使用'numpy'? – DSM 2013-02-26 18:18:36
定義「巨大」。另外,每行都有相同數量的整數嗎? – 2013-02-26 18:37:01