Fortran程序生成的文本文件包含需要重新格式化的“块”数据(Python脚本)。
此文件中的每个“块”数据对应于块开头指定的“时间:”。所有“块”都具有固定的大小和结构。
我需要从“Head”和“Moisture”列中提取对应于每个“Time:”的不同“Depths”(0,-1和-2)的数据。
注意:开头的标题不是重复“数据块”的一部分。
示例输入文件:
******* Program Simulation
*******
This is initial header information for Simulation
Date: 1. 6. Time: 15: 3:39
Units: L = cm , T = min , M = mmol
Time: 0.0000
Node Depth Head Moisture K
[L] [L] [-] [L/T]
1 0.0000 -37.743 0.0630 0.5090E-05
2 -1.0000 -36.123 0.0750 0.5090E-05
3 -2.0000 -33.002 0.0830 0.5090E-05
end
Time: 360.0000
Node Depth Head Moisture K
[L] [L] [-] [L/T]
1 0.0000 -0.1000E+07 0.0450 0.1941E-32
2 -1.0000 -253.971 0.0457 0.4376E-10
3 -2.0000 -64.510 0.0525 0.2264E-06
end
Time: 720.0000
Node Depth Head Moisture K
[L] [L] [-] [L/T]
1 0.0000 -0.1000E+07 0.0550 0.1941E-32
2 -1.0000 -282.591 0.0456 0.2613E-10
3 -2.0000 -71.829 0.0513 0.1229E-06
end
期望的输出:
Time Head(Depth=0) Head(Depth=-1) Head(Depth=-2) Moisture(Depth=0) Moisture(Depth=-1) Moisture(Depth=-2)
0.0000 -37.743 -36.123 -33.002 0.0630 0.0750 0.0830
360.0000 -0.1000E+07 -253.971 -64.510 0.0450 0.0457 0.0525
720.0000 -0.1000E+07 -282.591 -71.829 0.0550 0.0456 0.0513
我如何从每个“Time:”到“end”关键字逐块读取输入文件并重新格式化为所需的输出?
答案 0 :(得分:1)
这是解析部分:
import re
data = []
with open(xxxx) as f:
for line in f:
m = re.match(r'^\s+Time:\s+([\d.]+)', line)
if m:
data.append([float(m.group(1))])
elif re.match(r'^\s+\d+', line):
data[-1].append(map(float, line.strip().split()))
产生
[[0.0,
[1.0, 0.0, -37.743, 0.063, 5.09e-06],
[2.0, -1.0, -36.123, 0.075, 5.09e-06],
[3.0, -2.0, -33.002, 0.083, 5.09e-06]],
[360.0,
[1.0, 0.0, -1000000.0, 0.045, 1.941e-33],
[2.0, -1.0, -253.971, 0.0457, 4.376e-11],
[3.0, -2.0, -64.51, 0.0525, 2.264e-07]],
[720.0,
[1.0, 0.0, -1000000.0, 0.055, 1.941e-33],
[2.0, -1.0, -282.591, 0.0456, 2.613e-11],
[3.0, -2.0, -71.829, 0.0513, 1.229e-07]]]
从中打印所需的表格应该很容易。
答案 1 :(得分:1)
修改:我做了一些更改,因此实际运行。
from itertools import chain
def get_lines(f, n=1):
return [f.next() for i in xrange(n)]
class BlockReader(object):
def __init__(self, f, n=1):
self.f = f
self.n = n
def __iter__(self):
return self
def next(self):
return [self.f.next() for i in xrange(self.n)]
fmt = "{:<12}" + "{:<16}"*6 + "\n"
cols = [
"Time",
"Head(Depth=0)",
"Head(Depth=-1)",
"Head(Depth=-2)",
"Moisture(Depth=0)",
"Moisture(Depth=-1)",
"Moisture(Depth=-2)"
]
def main():
with open("simulation.txt") as inf, open("result.txt","w") as outf:
# throw away input header
get_lines(inf, 5)
# write output header
outf.write(fmt.format(*cols))
# read input file in ten-line chunks
for block in BlockReader(inf, 10):
# grab time value
time = float(block[1].split()[1])
# grab head and moisture columns
data = (line.split()[2:4] for line in block[6:9])
values = (map(float,dat) for dat in data)
h,m = zip(*values)
# write data to output file
outf.write(fmt.format(*chain([time],h,m)))
if __name__=="__main__":
main()
输出
Time Head(Depth=0) Head(Depth=-1) Head(Depth=-2) Moisture(Depth=0)Moisture(Depth=-1)Moisture(Depth=-2)
0.0 -37.743 -36.123 -33.002 0.063 0.075 0.083
360.0 -1000000.0 -253.971 -64.51 0.045 0.0457 0.0525
720.0 -1000000.0 -282.591 -71.829 0.055 0.0456 0.0513
答案 2 :(得分:0)
如果文件不是太大,你可以这样做:
f = open('somefile')
file = f.read()
blocks = file.split('Time:')[1:]