NumPy加载文件散布着标题

时间:2013-07-19 03:41:04

标签: python performance file parsing numpy

我正在尝试使用以下格式的重复块来解析文件:

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)])

2 个答案:

答案 0 :(得分: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,...)

答案 1 :(得分: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

和in python

from numpy import loadtxt
data = loadtxt("atoms.data")