当我编程时,我经常使用外部软件来进行繁重的计算,但随后在Python中分析结果。这些外部软件通常是Fortran,C或C ++,它们通过提供输入文件来工作。这可以是一个小文件,告诉哪个模式执行某些计算,或者它必须处理的大数据文件。这些文件通常使用某种格式(数据列之间有这么多空格)。例如,下面给出了我目前使用的数据文件。
This is a header. The first line is always a header...
7352.103 26.0 2.61 -8.397 11.2
7353.510 26.0 4.73 -1.570 3.5
7356.643 26.0 5.75 -2.964 9.0
7356.648 26.0 5.35 -3.187 9.0
7364.034 26.0 5.67 -5.508 1.7
7382.523 26.0 5.61 -3.935 1.9
我的问题是,是否存在用于创建此类输入文件的Python库,从阅读模板(由同事或外部软件的文档提供)?
通常我有NumPy
格式的所有列,并希望将模板作为示例提供给创建输入文件的函数。我不是在寻找一种蛮力方法,它可以很快变得丑陋。
我不确定在这里搜索什么,感谢任何帮助。
答案 0 :(得分:5)
我基本上可以用savetxt
复制你的样本。它的fmt
变量为我提供了与FORTRAN代码用于读取和写入文件相同的格式控制。它以与FORTRAN和C打印相同的方式保留空间。
import numpy as np
example = """
This is a header. The first line is always a header...
7352.103 26.0 2.61 -8.397 11.2
...
"""
lines = example.split('\n')[1:]
header = lines[0]
data = []
for line in lines[1:]:
if len(line):
data.append([float(x) for x in line.split()])
data = np.array(data)
fmt = '%10.3f %9.1f %9.2f %9.3f %20.1f' # similar to a FORTRAN format statment
filename = 'stack21865757.txt'
with open(filename,'w') as f:
np.savetxt(f, data, fmt, header=header)
with open(filename) as f:
print f.read()
制造
# This is a header. The first line is always a header...
7352.103 26.0 2.61 -8.397 11.2
7353.510 26.0 4.73 -1.570 3.5
...
修改
这是一个将示例行转换为格式的粗略脚本:
import re
tmplt = ' 7352.103 26.0 2.61 -8.397 11.2'
def fmt_from_template(tmplt):
pat = r'( *-?\d+\.(\d+))' # one number with its decimal
fmt = []
while tmplt:
match = re.search(pat,tmplt)
if match:
x = len(match.group(1)) # length of the whole number
d = len(match.group(2)) # length of decimals
fmt += ['%%%d.%df'%(x,d)]
tmplt = tmplt[x:]
fmt = ''.join(fmt)
return fmt
print fmt_from_template(tmplt)
# %10.3f%10.1f%10.2f%10.3f%29.1f
答案 1 :(得分:2)
调整hpaulj andwer以神奇地提取savetxt的fmt
from __future__ import print_function
import numpy as np
import re
example = """
This is a header. The first line is always a header...
7352.103 26.0 2.61 -8.397 11.2
7353.510 26.0 4.73 -1.570 3.5
7356.643 26.0 5.75 -2.964 9.0
7356.648 26.0 5.35 -3.187 9.0
7364.034 26.0 5.67 -5.508 1.7
7382.523 26.0 5.61 -3.935 1.9
"""
def extract_format(line):
def iter():
for match in re.finditer(r"\s+-?\d+\.(\d+)",line):
yield "%{}.{}f".format(len(match.group(0)),len(match.group(1)))
return "".join(iter())
lines = example.split('\n')[1:]
header = lines[0]
data = []
for line in lines[1:]:
if len(line):
data.append([float(x) for x in line.split()])
data = np.array(data)
fmt = extract_format(lines[1]) # similar to a FORTRAN format statment
filename = 'stack21865757.txt'
with open(filename,'w') as f:
print(header,file=f)
np.savetxt(f, data, fmt)
with open(filename) as f:
print (f.read())
制造
This is a header. The first line is always a header...
7352.103 26.0 2.61 -8.397 11.2
7353.510 26.0 4.73 -1.570 3.5
7356.643 26.0 5.75 -2.964 9.0
7356.648 26.0 5.35 -3.187 9.0
7364.034 26.0 5.67 -5.508 1.7
7382.523 26.0 5.61 -3.935 1.9
答案 2 :(得分:1)
如果您的标题始终相同,那么您可以查看pandas。这样,只需知道标题中列的名称,就可以非常轻松地移动列。即使标题并不总是相同,如果您可以从模板中获取标题,那么它仍然可以重新排列它。
如果我误解了这个问题,那么我很抱歉,但更具体的数据或更长的例子可能会有更多的帮助。