整数のリストのリストを含む巨大なテキスト ファイルを読みたいです。今、私は次のことをしています:
G = []
with open("test.txt", 'r') as f:
for line in f:
G.append(list(map(int,line.split())))
ただし、約 17 秒かかります (timeit 経由)。この時間を短縮する方法はありますか?もしかしたら、地図を使わない方法もあるかもしれません。
整数のリストのリストを含む巨大なテキスト ファイルを読みたいです。今、私は次のことをしています:
G = []
with open("test.txt", 'r') as f:
for line in f:
G.append(list(map(int,line.split())))
ただし、約 17 秒かかります (timeit 経由)。この時間を短縮する方法はありますか?もしかしたら、地図を使わない方法もあるかもしれません。
numpyにはとの機能がありますloadtxt
がgenfromtxt
、どちらも特に高速ではありません。広く配布されているライブラリで利用できる最速のテキストリーダーの1つは、(http://pandas.pydata.org/read_csv
)の関数です。私のコンピューターでは、1行に2つの整数を含む500万行を読み取るには、で約46秒、。で26秒、 。で1秒強かかります。pandas
numpy.loadtxt
numpy.genfromtxt
pandas.read_csv
結果を示すセッションは次のとおりです。(これはLinux、Ubuntu 12.04 64ビット上にあります。ここには表示されませんが、ファイルを読み取るたび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
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 倍高速です。
一般的な経験則として (ほぼすべての言語で)、 を使用read()
してファイル全体を読み取ると、一度に 1 行ずつ読み取るよりも速くなります。メモリに制約されていない場合は、ファイル全体を一度に読み取り、改行でデータを分割してから、行のリストを反復処理します。
また、一括挿入によってデータをデータベースに取り込み、セット操作でレコードを処理することもできます。一括挿入ソフトウェアはこのタイプのタスクに最適化されているため、何をしなければならないかによっては、それがより高速になる場合があります。
最も簡単な高速化は、PyPy http://pypy.org/を使用することです。
次の問題は、ファイルをまったく読み取らないことです (可能な場合)。代わりに、ストリームのように処理します。
多くの場合、リスト内包表記の方が高速です。
G = [[int(item) item in line.split()] for line in f]
それを超えて、PyPyとCythonとnumpyを試してください