2

できるだけ効率的に Python で固定幅のテキスト ファイルを読み取ることに興味があります。具体的には、ほとんどの場合、フラット ファイル内の 1 つまたは複数の列に関心がありますが、レコード全体には関心がありません。

一度に 1 行ずつファイルを読み取り、行全体をメモリに読み取った後に目的の列を抽出するのは非効率的だと思います。左から右、上から下に読むのではなく、上から下、左から右に、目的の列のみを読むオプションがあると思います。

そのようなことは望ましいことですか? もしそうなら、それは可能ですか?

4

4 に答える 4

4

ファイルは、ビットの (1 次元) シーケンスとして配置されます。「線」は、人間が読みやすくするために追加した便利なものです。したがって、一般的に、あなたが求めていることはプレーンファイルでは不可能です。これをやってのけるには、レコードの開始位置を見つける何らかの方法が必要です。最も一般的な方法は次の 2 つです。

  • 改行記号を検索します (つまり、ファイル全体を読み取ります)。
  • 各レコードが固定された with を使用してレイアウトされるように、特別に配置されたレイアウトを使用します。そうすれば、 のような低レベルのファイル操作を使用seekして、必要な場所に直接移動できます。これにより、ファイル全体を読み取る必要がなくなりますが、手動で行うのは面倒です。

問題にならない限り、ファイルの読み取りパフォーマンスについてはあまり心配しません。はい、ファイルをメモリ マップできますが、OS が既にキャッシュしている可能性があります。はい、データベース形式 (たとえば、sqlalchemyを介した sqlite3 ファイル形式) を使用できますが、おそらく手間をかける価値はありません。

「固定幅」に関する補足:これは正確にはどういう意味ですか? 「すべての列が常にレコードの先頭から相対的に同じオフセットで始まる」ことを本当に意味する場合は、Pythonseekを使用して、興味のない過去のデータをスキップできます。

于 2011-02-26T21:58:55.580 に答える
3

線の大きさは?各レコードが巨大でない限り、行全体ではなく、関心のあるフィールドだけを読んでも、おそらくほとんど違いはありません。

フォーマットが固​​定された大きなファイルの場合、ファイルをmmapすることで何かが得られる場合があります。私はPythonではなくCでこれを行っただけですが、ファイルをmmapして適切なフィールドに直接アクセスするのはかなり効率的です。

于 2011-02-26T21:46:43.930 に答える
3

フラットファイルは、あなたがやろうとしていることには適していません。私の提案は、(sqlite3 を使用して) ファイルを SQL データベースに変換してから、必要な列だけを読み取ることです。SQLite3 は非常に高速です。

于 2011-02-26T21:49:00.683 に答える
1

本当に固定幅の場合は、 read(N) を呼び出すだけで、ある行の列の終わりから次の列の始まりまでの固定バイト数をスキップできるはずです。

于 2011-02-26T21:53:53.627 に答える