简体   繁体   English

从 python 中的数据文件读取和绘图

[英]Reading and plotting from a data file in python

I am a beginner in python and i have some question that i need assistance from you.我是 python 的初学者,我有一些问题需要您的帮助。 I am sorry if the question is too basic.如果问题太基本,我很抱歉。

I have a data file which looks like below (the file is long with more than 4000 lines);我有一个如下所示的数据文件(文件很长,超过 4000 行);

4
0.1 0.1
1.5 0.1
0.5 0.6
1.5 0.6
0.0000000E+00 0.0000000E+00 0.0000000E+00 -1.3180656E-04
0.0000000E+00 0.0000000E+00 0.0000000E+00 -2.8582822E-05
0.0000000E+00 0.0000000E+00 0.0000000E+00 -1.5833791E-04
0.0000000E+00 0.0000000E+00 0.0000000E+00 -9.9146621E-05
2.5294579E-02 -3.7180660E-01 7.5958102E-02 6.4079851E-01
2.5294579E-02 7.1739070E+00 6.4493904E-01 6.6945873E-01
2.5294579E-02 3.1476634E+00 8.8396035E-01 -1.4551238E-02
2.5294579E-02 1.6825711E+00 5.1869466E+00 2.4610339E-02
3.2829473E-02 -5.1518883E+00 5.4573026E+00 6.7564747E-01
3.2829473E-02 1.9206643E+01 -1.2400739E+00 6.9728887E-01
3.2829473E-02 -1.5529481E+01 4.6126603E+00 -5.2802531E-03
3.2829473E-02 -4.3019722E+00 7.6228330E+00 5.4802021E-02
3.6500080E-02 -1.0096638E+01 1.1882060E+01 7.0272428E-01
3.6500080E-02 2.8727686E+01 -7.0275729E+00 6.5145852E-01
3.6500080E-02 -3.7448674E+01 -4.4589296E+00 2.2430999E-02
3.6500080E-02 -1.1295979E+01 5.3019553E+00 8.0316341E-02

I would like to write a python code that reads the 6th line, then skips the next three lines and reads the 10th line, then 14th line and so on (In other words the code should skip the first five lines, then reads the 6th line skips next 3 lines, read the next line and so on ).我想写一个 python 代码读取第 6 行,然后跳过接下来的三行并读取第 10 行,然后是第 14 行,依此类推(换句话说,代码应该跳过前五行,然后读取第 6 行跳过接下来的 3 行,阅读下一行,依此类推)。

Then the code should use these read lines to plot the second, third and fourth columns along the y-axis and the first column along x-axis.然后代码应该使用这些读取行到 plot 沿 y 轴的第二、第三和第四列以及沿 x 轴的第一列。

I have tried to write the code below but it doesn't do extactly what i want.我试图编写下面的代码,但它并没有完全符合我的要求。

import numpy as np 
import matplotlib.pyplot as plt 
from math import* 
import scipy.optimize as sci 
#loading data 
with open('data.his') as f: 
d=f.readlines()[5:] 
#assigning the columns 
time=d[:,0] 
vx=d[:,1] 
vy=d[:,2] 
temp=d[:,3] 
# plotting
plt.plot(time,temp, label='Temperature variation') 
plt.xlabel('Time [s]') 
plt.ylabel('Temperature [K]') 
plt.legend() 
plt.show() 

Thank you in advance for your assistance.预先感谢您的协助。

You can use the modulo operator % to pick only every fourth line.您可以使用模运算符%仅选择每四行。

time = []

for j, c in enumerate(d):
    if j % 4 == 0:
        time.append(c[0])

Same for vx , vy and temp (using the corresponding colum indexes). vxvytemp相同(使用相应的列索引)。

TL;DR TL;博士

data  = dict(zip(('x', 'y1', 'y2', 'y3', ...), # as many as your columns
                 (c for c in zip(*((float(s) for s in l.split())
                      for n, l in enumerate(open(...)) if n>4 and not (n-5)%4)))))
plt.plot(cols['x'], cols['y1'], label='Y1')
...
plt.legend() ; plt.show()

Unfolded, well commented initial code展开的、注释良好的初始代码

You can do what you want in many different ways, personally I would start like this (please read the inline comments for the explanation of the code) and later...你可以用许多不同的方式做你想做的事,我个人会这样开始(请阅读内联注释以了解代码的解释),然后......

# open the file and slurp its contents
with f as open(...):
    lines = f.readlines()

# throw away the uninteresting lines,
# using slice notation, [5::4] means:
#   from line #6 ("[5:", Python counts from 0) to the end ("::") with a step of 4 (":4]")
lines = lines[5::4]

# turn space separated strings into floats
# for every line in the interesting lines, split it and
# make a list containing the numerical values
# numbers is a list of lists, each list corresponding to a line in the file
numbers = [[float(s) for s in line.split()] for line in lines]

# transpose the numbers, i.e., turn columns into rows, so that now
# numbers is a list of lists, each list corresponding to a COLUMN of data
numbers = [column for column in zip(*numbers)]

# plot the relevant columns (remember that Python counts from 0)
plt.plot(numbers[0], numbers[1], label='1')
plt.plot(numbers[0], numbers[2], label='2')
...
plt.legend()

First, reasonable optimisation一、合理优化

In place of代替

lines = lines[5::3]
numbers = [[float(s) for s in line.split()] for line in lines]

you probably should coalesce the two statements into您可能应该将这两个语句合并为

numbers = [[float(s) for s in line.split()] for line in lines[5::3]]

I have used two statements in the example code because it was easier to comment appropriately.我在示例代码中使用了两个语句,因为这样更容易进行适当的注释。


A less reasonable optimisation不太合理的优化

Further down into the narrowing path of coalescing,进一步向下进入合并的狭窄路径,

cols = [c for c in zip(*((float(s)for s in l.split())for n,l in enumerate(open(...))if n>4 and not (n-5)%4))]
plt.plot(cols[0], cols[1], label='1')
...

Last optimisation, not unreasonable...最后的优化,不无道理...

Use a dictionary!使用字典!

data  = dict(zip(('x', 'y1', 'y2', 'y3', ...), # as many as your columns
                 (c for c in zip(*((float(s) for s in l.split())
                      for n, l in enumerate(open(...)) if n>4 and not (n-5)%4)))))
plt.plot(data['x'], data['y1'], label='Y1')
...
plt.legend() ; plt.show()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM