0

次の形式の繰り返しブロックを含むファイルを解析しようとしています:

ITEM: TIMESTEP
5000
ITEM: NUMBER OF ATOMS
4200
ITEM: BOX BOUNDS pp pp ff
0 47.6892
0 41.3
-11.434 84.1378
ITEM: ATOMS id type z vx 
5946 27 11.8569 0.00180946 
5948 28 11.1848 -0.0286474 
5172 27 12.1796 0.00202046 
...

ここで ... はNUMBER OF ATOMSエントリ (この特定のファイルでは 4200) になります。各ファイルには、これらのブロックの多くが連続して含まれており、100 万から 500 万行の範囲になります。

各ブロックの最初の 9 行に含まれるすべてのヘッダー データを完全に無視し、すべての "z" 値 (データ エントリの 3 列目) を含む配列と "vx" 値を含む配列 (データ入力の 4 列目)。

各ブロックのヘッダーは、ITEM: TIMESTEP エントリに続く番号を除いて、ファイル内で常に同じです。ヘッダー形式はファイル間で同じままで、ファイルはエントリ (アトム) の数だけが異なります。

以前に作業していたいくつかの短いファイルのトリックを行う信じられないほど汚いコードを書きましたが、これらのファイルでは非常に遅いです。genfromtxt 関数を使用してみましたが、この場合に必要なことを行うためにそれを曲げる方法が見つかりませんでした。これをより速くするためのヒントはありますか?

編集:

以下は私のために働いた:

grep -E '^[.-0123456789]+ [.-0123456789]+ [.-0123456789]+ [.-0123456789]'

これがしたように:

with open(data, 'r') as fh:
    wrapper = (i for i in fh if re.match(r'^[-.1234567890]+ [-.1234567890]+ [-.1234567890]+ [-.1234567890]',i))
    z_vx = np.genfromtxt(wrapper, usecols=(2,3))

これは私のケースでは最速でした:

regexp = r'\d+\s+\d+\s+([0-9]*\.?[0-9]+)\s+([-+]?[0-9]*\.?[0-9]+)\s+\n'
data = np.fromregex(file_path, regexp, dtype=[('z', float), ('vx', float)])
4

2 に答える 2

1

速度が必要な場合はgrep、関連する行のみを使用してからnp.genfromtxt().

次のようにgrepします(関連する行に4つの数値フィールドがあると思いましたか?):

grep -P '^[-.0123456789]+ [-.0123456789]+ [-.0123456789]+ [-.0123456789]+$'

より Pythonic な解決策は、次のようなジェネレーターでファイル ハンドルをラップすることです。

wrapper = (i for i in fh if re.match(r'^[-.1234567890]+ [-.1234567890]+ [-.1234567890]+ [-.1234567890]+$',i))
np.genfromtxt(wrapper,...)
于 2013-07-19T03:54:42.490 に答える