我有很大的fortran生成的ASCII文件,其格式如下:

x y z  num_line index
1 float
2 float
...
num_line float
x2 y2 z2 num_line2 index2
1 float
2 float
...
num_line2 float
...


块的数量可以增加到数千,每个块中的行数可以增加到数百。

让我们举一个我得到的例子:

0.0 0.0 0.0  4 0
1 0.5
2 0.9
3 0.4
4 0.1
0.0 0.0 1.0  4 1
1 0.2
2 0.2
3 0.4
4 0.9
0.0 1.0 2.0  5 2
1 0.7
2 0.6
3 0.9
4 0.2
5 0.7


我想从中得到什么(作为一个numpy矩阵):

0.5 0.2 0.7
0.9 0.2 0.6
0.4 0.4 0.9
0.1 0.9 0.2
nan nan 0.7


当然,我可以使用:

my_mat = []
with open("myfile", "r") as f_in:
    niter = int(f_in.readline().split()[3])
    while niter:
        curr_vect = zeros(niter)
        for i in xrange(niter):
            curr_vect[i] = float(f_in.readline().split()[1])
        my_mat.append(curr_vect)
        line = f_in.readline()
        if line is not None:
            niter = int(line.split()[3])
        else:
            niter = False
my_mat = array(my_mat)


问题在于这并不是真正有效,而且过于复杂。我已经知道numpy的loadtxtgenfromtxt,但是它们似乎不适用于这些地方。

我正在寻找更快,更易读的东西。任何的想法?

编辑:

请原谅我,我的问题还不完整,有些人因为我而失去了时间。这是此类块的真实示例:

3.571428571429E-02 3.571428571429E-02-3.571428571429E-02         1   35
       1 -0.493775207966779
       2  0.370269037864060
       3  0.382332033744703
       4  0.382332033744703
       5  0.575515346181205
       6  0.575515346181216
       7  0.575562530624028
       8  0.639458035564442
       9  0.948445367602052
      10  0.948445367602052
      11  0.975303238888803
      12   1.20634795229899
      13   1.21972845646758
      14   1.21972845646759
      15   1.52659950368213
      16   2.07381346028515
      17   2.07629743909555
      18   2.07629743909555
      19   2.15941179949552
      20   2.15941179949552
      21   2.30814240005132
      22   2.30814240005133
      23   2.31322868361483
      24   2.53625115348660
      25   2.55301153157825
      26   2.55301153157826
      27   2.97152031842301
      28   2.98866790318661
      29   2.98866790318662
      30   3.24757159459268
      31   3.27186643004142
      32   3.27186643004143
      33   3.37632477135298
      34   3.37632477135299
      35   3.55393884607834

最佳答案

import numpy as np
from itertools import groupby,izip_longest

def f1(fname):
    with open(fname) as f:
        return np.matrix(list(izip_longest(
               *(map(lambda x: float(x[1]),v)
               for k,v in groupby(map(str.split,f),
               key=lambda x: len(x) == 2) if k),
               fillvalue=np.nan)))
d1('testfile')


出:

matrix([[ 0.5,  0.2,  0.7],
        [ 0.9,  0.2,  0.6],
        [ 0.4,  0.4,  0.9],
        [ 0.1,  0.9,  0.2],
        [ nan,  nan,  0.7]])


编辑:

至于性能,我在np.genfromtxt解决方案@TheodrosZelleke上进行了测试,它的速度似乎快了五倍。

09-06 19:02