2017-04-05 80 views
0

默認情況下,我的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

回答

0

考慮使用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

0

這是我想出來的作品。

#!/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()