从.asc文件中删除最后n行并使用matplotlib绘图

时间:2017-06-27 10:27:02

标签: python python-2.7 matplotlib

我有一个.asc文件,看起来像这样(x和y列)

48.069868   11993  
49.111533   11824   
50.153094   11325  
51.194551   11229  
52.235905   11318

Date and Time:                   Wed May 31 14:47:29 2017   
Software Version:              4.20.30007.0       
Temperature (C):              -60
Model:                        DU970_UVB     

在文件末尾有一些字符串行。所以我使用matplotlib作为

进行绘图
  import matplotlib.pyplot as plt 

  plt.plotfile('600_1%_532e_Mo F1_80sec.asc', delimiter=' ', cols=(0, 1), 
           names=('col1', 'col2'), )
  plt.show()

现在如果要删除最后一行,我可以使用行[: - 1],但是:

  1. 是否可以在不指定数字的情况下删除最后n行。我的意思是如果python可以读取有多少行有字符串,它将只删除那些行。
  2. 我不想永久删除这些行。只是为了绘制我想删除它们的数据点。

3 个答案:

答案 0 :(得分:1)

我不知道如何使用plotfile功能,但据我所知plotfile使用函数csv2recdocs)。在您的情况下,您可以执行以下操作:

import matplotlib.pyplot as plt
from matplotlib.mlab import csv2rec


def converter(value):
    try:
        return float(value)
    except ValueError:
        pass

if __name__ == "__main__":
    data = csv2rec(
        "'600_1%_532e_Mo F1_80sec.asc'",
        delimiter=" ",
        names=("col1", "col2"),
        converterd={
            "col1": converter,
            "col2": converter,
        }
    )
    data = filter(lambda i: i[0], data)
    plt.plot(*zip(*data))
    plt.show()

如果转换器函数无法将值转换为float,则返回None。因此,data将为所有不可兑换商品设置None个值。之后你可以过滤它。

答案 1 :(得分:1)

如果您仔细阅读文档,可以看到,

matplotlib.pyplot.plotfile(fname, cols=(0, ), 
plotfuncs=None, comments='#', skiprows=0, checkrows=5,   
 delimiter=',',names=None, subplots=True, newfig=True, **kwargs)

有一个名为评论的可选参数。那意味着什么?这意味着从文件中读取但是跳过那些作为注释的行。

你也说过,

  

我不想永久删除这些行。仅用于绘制我想要删除它们的数据点

所以你不想删除它们,但你不想使用它们。所以把它们改成评论!

<强> my_file.asc

48.069868   11993  
49.111533   11824   
50.153094   11325  
51.194551   11229  
52.235905   11318

Date and Time:                   Wed May 31 14:47:29 2017   
Software Version:              4.20.30007.0       
Temperature (C):              -60
Model:                        DU970_UVB

所以逻辑就是遗漏数字。只将作为字符串的行转换为注释!如何使用re

tf = open('my_file.asc','r+')
d = tf.readlines()
tf.seek(0)
for line in d:
    s=re.search(r'[a-zA-Z]',line)
    if s:
        tf.write('#'+line)
    else:
        tf.write(line)
tf.truncate()
tf.close()

所以我正在做的是搜索每一行,如果该行恰好以字符串开头,则将line替换为'#'+line。 (将其更改为评论)。所以在此之后,这就是my_file.asc的外观,

48.069868   11993  
49.111533   11824   
50.153094   11325  
51.194551   11229  
52.235905   11318

#Date and Time:                   Wed May 31 14:47:29 2017   
#Software Version:              4.20.30007.0       
#Temperature (C):              -60
#Model:                        DU970_UVB

之后你得到了你想要的东西,非常简单。与您的代码相同。这是完整的解决方案工作解决方案

import itertools
import matplotlib.pyplot as plt
import re

tf = open('my_file.asc','r+')
d = tf.readlines()
tf.seek(0)
for line in d:
    s=re.search(r'[a-zA-Z]',line)
    if s:
        tf.write('#'+line)
    else:
        tf.write(line)
tf.truncate()
tf.close()


import matplotlib.pyplot as plt 

plt.plotfile('my_file.asc', delimiter=' ',comments='#', cols=(0, 1), 
           names=('col1', 'col2'), )
plt.show()

我刚刚添加comments='#'瞧!你得到了你想要的东西而没有删除那些线。 Plot_Figure

答案 2 :(得分:0)

csv2rec(这是引擎盖下调用的函数)相同,plotfile似乎接受文件句柄,除了文件路径(虽然没有明确提到here)。 / p>

如果你能负担得起将文件存储到内存中(阅读:你没有使用巨大的文件),你可以使用StringIO.StringIO(Python 2.7)或io.StringIO(Python 3)。

StringIO是一个类似文件的对象,您可以在其中复制文件的内容,同时应用其他逻辑(即跳过页脚行)。生成此新对象后,您可以将其传递给plotfile。这是一个例子:

import matplotlib.pyplot as plt 
from StringIO import StringIO
# from io import StringIO

footerlines = 5
with open('example.asc', 'r') as fhandle:
    temp = StringIO()
    for line in fhandle.readlines()[:-footerlines]:
        temp.write(line)
# bring the pointer back to the beginning of the file-like object
temp.seek(0)

plt.plotfile(temp, delimiter=' ', cols=(0, 1), names=('col1', 'col2'))
plt.show()