ファイル全体をトラバースせずにランダムな行にアクセスするためのPythonファイルタイプはありますか?大きなファイル内を検索する必要があります。すべてをメモリに読み込むことはできません。
任意のタイプまたは方法をいただければ幸いです。
ファイル全体をトラバースせずにランダムな行にアクセスするためのPythonファイルタイプはありますか?大きなファイル内を検索する必要があります。すべてをメモリに読み込むことはできません。
任意のタイプまたは方法をいただければ幸いです。
これは、ある種のものmmap
が設計されたように思えます。オブジェクトは、ファイルへのmmap
文字列のようなインターフェイスを作成します。
>>> f = open("bonnie.txt", "wb")
>>> f.write("My Bonnie lies over the ocean.")
>>> f.close()
>>> f.open("bonnie.txt", "r+b")
>>> mm = mmap(f.fileno(), 0)
>>> print mm[3:9]
Bonnie
ご参考までに、mmap
オブジェクトを以下に割り当てることもできます。
>>> print mm[24:]
ocean.
>>> mm[24:] = "sea. "
>>> print mm[:]
My Bonnie lies over the sea.
linecacheを使用できます:
import linecache
print linecache.getline(your_file.txt, randomLineNumber) # Note: first line is 1, not 0
行は任意の長さである可能性があるため、ファイル全体をトラバースせずにランダムな行(「実際にランダムな数の行」または「私が選択した任意の番号の行」を意味するかどうか)を取得することはできません。 。
kinda-sorta-randomで十分な場合は、ファイル内のランダムな場所を探して、ラインターミネータに到達するまで先読みすることができます。しかし、(たとえば)行番号1234を見つけたい場合は役に立ちません。また、実際にランダムに選択された行が必要な場合は、行を不均一にサンプリングします。
ファイルオブジェクトには、そのファイル内の特定のバイトに値をとることができるseekメソッドがあります。大きなファイルをトラバースするには、ファイルを繰り返し処理して、各行の値を確認します。ファイルオブジェクトを反復処理しても、ファイルの内容全体がメモリに読み込まれるわけではありません。
固定長レコードはありますか? そうであれば、シークを使用して二分探索アルゴリズムを実装できます。
それ以外の場合は、ファイルを SQLlite データベースにロードします。それをクエリします。
はい、ランダムな行を簡単に取得できます。ファイル内のランダムな位置をシークし、\n またはファイルの先頭に到達するまで先頭に向かってシークし、行を読み取ります。
コード:
import sys,random
with open(sys.argv[1],"r") as f:
f.seek(0,2) # seek to end of file
bytes = f.tell()
f.seek(int(bytes*random.random()))
# Now seek forward until beginning of file or we get a \n
while True:
f.seek(-2,1)
ch = f.read(1)
if ch=='\n': break
if f.tell()==1: break
# Now get a line
print f.readline()
File オブジェクトはシークをサポートしていますが、必ずバイナリ、つまり "rb" として開いてください。
特にデータがすでに内部フォーマットになっている場合は、ランダム アクセスに mmap モジュールを使用することもできます。