Python:读取可变数量的列数

问题描述:

默认情况下,我的python脚本会从标准输入读取数据并写入标准输出。但是,如果我指定某些命令行选项,那么我可以从文件读取数据或写入文件。Python:读取可变数量的列数

该脚本只会读取由制表符和/或空格分隔的两列数字。我需要它,它会读取2列或更多列的数字(我有其他脚本,其中一个输出管道输入另一个)。

这是我有:

def main(argv): 
    fin=sys.stdin 
    fout=sys.stdout 
    w=3 
    plot=False 
    graph=False 
    ifile="stdin" 
    ofile="stdout" 
    filt="Median" 
    ydata=False 
    try: 
     opts, args=getopt.getopt(argv,"hi:o:w:ps:qf:y",["ifile=","ofile="]) 
    except getopt.GetoptError: 
    print sys.argv[0] + ' [-i <inputfile>] [-o <outputfile>] [-w <int>] [-p] [-s <imagefile>] [-q] [-f <int>] [-y]' 
    sys,exit(1) 
    for opt, arg in opts: 
    if opt=='-h': 
     print sys.argv[0] + ' [-i <inputfile>] [-o <outputfile>] [-w <int>] [-p] [-s <imagefile>] [-q] [-f <int>] [-y]n' 
     print ' -w filter window size (default=3)' 
     print ' -p display plot' 
     print ' -s save plot as imagefile (eps, jpeg, jpg, pdf, pgf, png, ps, raw, rgba, svg, svgz, tif, tiff)' 
     print ' -i if no inputfile is specified, read from STDIN' 
     print ' -o if no outputfile is specified, print to STDOUT' 
     print ' -f integer: 1=median (default), 2=moving average, 3=Wiener' 
     print ' -q quiet; suppress output' 
     print ' -y include y-data in output' 
     sys.exit() 
    elif opt in ("-i", "--ifile"): 
     ifile=arg 
    elif opt in ("-o", "--ofile"): 
     ofile=arg 
    elif opt in ("-q"): 
     ofile="/dev/null" 
    elif opt in ("-w"): 
     w=int(arg) 
    elif opt in ("-p"): 
     plot=True 
    elif opt in ("-f"): 
     if int(arg)==2: 
     filt="Moving Average" 
     elif int(arg)==1: 
     filt="Median" 
     elif int(arg)==3: 
     filt="Wiener" 
    elif opt in ("-s"): 
     graph=True 
     imagefile=arg 
    elif opt in ("-y"): 
     ydata=True 

    fin=open(ifile,'r') 
    lines=fin.readlines() 
    fin.close() 

# Initialize two lists 
    xl = [] 
    y1l = [] 

    for line in lines: 
     p = line.split() 
     xl.append(float(p[0])) 
     y1l.append(float(p[1])) 

# Convert the lists to arrays 
    x = np.array(xl) 
    y1 = np.array(y1l) 

    if filt=="Median": 
    yf=median(y1,width=w) 
    elif filt=="Moving Average": 
    yf=movingaverage(y1,w) 
    elif filt=="Wiener": 
    yf=wiener(y1,mysize=w) 

    fout=open(ofile,'w') 
    if ydata: 
    outdata=np.array([x,y1,yf]) 
    fmt=['%4.1f','%13.5e','%13.5e'] 
    else: 
    outdata=np.array([x,yf]) 
    fmt=['%4.1f','%13.5e'] 
    outdata=outdata.T 
    np.savetxt(fout, outdata, fmt) 
    fout.close() 

第一列将被存储在一个所谓的XL列表,然后转化成称为X的阵列。

第二列将存储在名为y1l的列表中,然后转换为一个名为y1的数组。

第三列(如果有的话)将存储在名为y2l的列表中,然后转换为称为y2的数组。

依此类推。

而列的数量应该存储在一个变量中。

或者,也许,最好将所有输入数据存储到多维列表中,然后将数组存储起来?实际上我甚至不需要这些清单;它们仅用于中间步骤以将数据存入数组。如果可以跳过将数据存储在列表中,并直接将数据存储到数组中,那将会更好。

+0

请包括'import'行和定义的方法,如* movingaverage *,* median *,* weiner *的重现性。如何计算两列后的变量列? Medians /移动整个阵列的avgs/weiners?是第一列,* xl *指示符字段? – Parfait

+0

功能无关紧要;他们与我问的问题没有任何关系。你可以的东西了: 高清位数(X,W): 返回X 高清movingaverage(X,W): 返回X 高清维纳(X,W): 返回X 的进口: import sys,getopt import matplotlib.pyplot as plt import numpy as np – Mannix

考虑使用numpy.loadtxt直接加载带有所有列的文本文件,避免使用嵌套列表的for循环。然后,如果需要,使用numpy.apply_along_axis跨列运行功能。

mat = np.loadtxt(ifile, delimiter="\t") 

if filt=="Median": 
    output_mat = np.apply_along_axis(median, 0, w) 

elif filt=="Moving Average": 
    output_mat = np.apply_along_axis(movingaverage, 0, w) 

elif filt=="Wiener": 
    output_mat = np.apply_along_axis(weiner, 0, w) 

np.savetxt(ofile, output_mat, delimiter='\t') 
+0

至此为止。假设我要绘制的数据... 直列'进口numpy的为NP 进口matplotlib.pyplot如PLT 如果= “2col.dat” DAT = np.loadtxt(IF1) plt.plot( dat [:,0],dat [:,1]) plt.show()' 这很好,如果我知道有两列。但是如果有更多的专栏,我不知道有多少? 假设我想让第一列是'x'轴,剩下的是'y1','y2',...,'yn'和'n'是未知的。 – Mannix

这是我想出来的作品。

#!/usr/bin/python 

import numpy as np 
import sys 
import os 
import matplotlib.pyplot as plt 
import math 

# set the default input to STDIN 
infile=sys.stdin 

# load the data from input 
data=np.loadtxt(infile) 
rows=len(data) 
cols=len(data[0]) 

# find the minimum and maximum x-values 
xmin=min(data[:,0]) 
xmax=max(data[:,0]) 

# create the plot 
fig=plt.figure() 
fig.set_size_inches(16,9) 
fig.set_dpi(120) 
plt.plot(data[:,0],data[:,1:]) 
plt.ylim(ymin=1e-6) 
plt.xlim(xmin,xmax) 
plt.grid(which='major',linestyle='-',linewidth='0.3') 
plt.xlabel('energy (eV/u)') 
plt.ylabel(r'cross section (10$^{-16}$ cm$^{2}$)') 
plt.xscale('log',basex=10) 
plt.yscale('log',basey=10) 
plt.show()