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)。每个文件连续包含许多这样的块,范围从 1 到 5 百万行。

我想完全忽略每个块的前 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 回答
0

我有一个类似的问题。最终使用sed,所以在标题前添加一个#,然后使用np.loadtxt.

所以bash脚本是

for i in $( ls *.data )
   do
     b = `basename $i .data`
     sed '1,9{/^#/!s/^/#/}' $i > $b.tmp
     rm $i
     mv $b.tmp $i
   done

和蟒蛇

from numpy import loadtxt
data = loadtxt("atoms.data")
于 2013-07-19T06:07:44.433 回答