Python: loadtxt: чтение числовых данных и строк комментариев из файла - PullRequest
0 голосов
/ 23 февраля 2019

У меня есть простой скрипт на 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(), как я делал выше.

Что вы порекомендуете?

1 Ответ

0 голосов
/ 23 февраля 2019

Я бы сделал это:

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

Теперь header.split() выдаст вам список столбцов:

['#',
 '(eV/u)',
 '6g(¹G)',
 '6h(¹H)',
...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...