首页 > 解决方案 > Python:loadtxt:从文件中读取数值数据和注释行

问题描述

我有一个简单的 python 脚本来读取数据文件并绘制它。这里是:

#!/usr/bin/python
import sys
import os
import matplotlib.pyplot as plt
import numpy as np
import ntpath
import argparse

def MainMenu(argv):
    parser=argparse.ArgumentParser(description="Plot MCLZ cross-sections.",prog=sys.argv[0])
    parser.add_argument("-i",help="Input file.",type=argparse.FileType('r'),metavar="str",dest="InFile",default=sys.stdin)
    parser.add_argument("-s",help="Save image file.",type=str,metavar="str",dest="ImgFile")
    parser.add_argument("-q",help="Quiet; do not display plot.",action="store_true",dest="quiet")
    parser._actions[0].help="Show help message and exit."
args=parser.parse_args(None if argv else ["-h"])
    return args

def MakeFig(data,args):
    rows=len(data)
    cols=len(data[0])
    xmin=min(data[:,0])
    xmax=max(data[:,0])
    fig=plt.figure(args.InFile.name)
    fig.set_size_inches(16.0,9.0)
    fig.set_dpi(120)
    plt.style.use("default")
    plt.plot(data[:,0],data[:,-1],'-',color="Black")
    color_idx=np.linspace(0,1,cols-1)
    for i,j in zip(range(cols-2,0,-1),color_idx):
        plt.plot(data[:,0],data[:,i],'-',color=plt.cm.gist_rainbow(j))
    plt.ylim(ymin=1e-6)
    plt.xlim(xmin,xmax)
    plt.grid(which='major',linestyle='-',linewidth='0.3')
    plt.xlabel(r'energy ($\frac{eV}{u}$)')
    plt.ylabel(r'cross section (10$^{-16}$ cm$^{2}$)')
    plt.xscale('log',basex=10)
    plt.yscale('log',basey=10)
    return fig

def main(argv):
    args=MainMenu(argv)
    data=np.loadtxt(args.InFile)    
    fig=MakeFig(data,args)
    if(args.quiet==False):
        plt.show()
    if(args.ImgFile):
        fig.savefig(args.ImgFile,dpi=120)

if __name__=="__main__":
    main(sys.argv[1:])

它做我想要的。然而,没有传说。我想要一个传奇。

图例标签位于输入文件的注释行中。

输入文件可以有可变数量的数据列。第一列将始终是x值。

# Magic number=03052015, 03 May 2015
# Single electron capture cross sections, nl state-selective
# Ne^9+ + H -> Ne^8+ + H^+
# Method=MCLZ
# Fname Lname et al. 2015, to be submitted
# ----------------------------------------------------------------------------
# Energy                Cross sections (10^-16 cm^2)
# (eV/u)        6g(¹G)          6h(¹H)          6f(¹F)          6d(¹D)          6p(¹P)          6s(¹S)          5g(¹G)          5f(¹F)          5d(¹D)          5p(¹P)          5s(¹S)          4f(¹F)          4d(¹D)          4p(¹P)          4s(¹S)          3d(¹D)          3p(¹P)          3s(¹S)          2p(¹P)          2s(¹S)          1s(¹S)          Total
1.000e-03       1.4776575e+02   1.7912626e+01   3.3462628e+02   1.9095364e+02   3.1276734e+01   6.2973301e+00   2.7468161e+00   2.3678743e-02   3.9230170e-09   8.1993422e-19   8.8673478e-24   1.5223718e-25   2.7018743e-34   4.8461238e-50   9.1037642e-59   1.4490583e-62   7.8949338e-74   3.7299268e-81   4.5993532e-83   5.4748211e-85   1.8820422e-85   7.3160285e+02
1.053e-03       1.4035132e+02   1.7013729e+01   3.1787085e+02   1.8143965e+02   2.9728031e+01   5.9865955e+00   2.6114108e+00   2.2513903e-02   3.7310299e-09   7.8009353e-19   8.4379868e-24   1.4486669e-25   2.5712078e-34   4.6122120e-50   8.6648019e-59   1.4192296e-62   7.7128879e-74   3.6383824e-81   4.3776881e-83   5.2109659e-85   1.8265794e-85   6.9502410e+02
...
...
...

我不知道如何从第 8 行获取标签numpy.loadtxt()。我知道默认的注释行标识符是#. 我想我可以改变它,读入文件,并忽略以 . 开头的前 7 行#

或者也许我可以读两次文件。第一次,忽略除以 开头的行之外的所有行# (eV/u)numpy.loadtxt()然后像我上面做的那样再读一遍。

你有什么建议吗?

标签: pythonnumpy

解决方案


我会这样做:

with open(args.InFile) as infile:
    for _ in range(8):
        header = next(infile)

现在header.split()将为您提供列列表:

['#',
 '(eV/u)',
 '6g(¹G)',
 '6h(¹H)',
...

推荐阅读