【问题标题】:Reading selected parts of a file of unknown name读取未知名称文件的选定部分
【发布时间】:2016-11-11 11:41:49
【问题描述】:

我有很多名称未知的数据文件。我想出了一种方法让它们全部被读取和打印,但我想制作它们的图表,所以我需要一种可行的数据。

数据文件的排列非常整齐(标题的每一行都包含有关其中存储内容的信息),但是我在编写选择所需数据的脚本时遇到了麻烦。文件的前 50 多行包含我只需要使用其中一些的标题,这在使用类似以下内容时没有问题:

    for filename in glob.glob(fullpath):
        with open(filename, 'r') as f:
            for line in f:
                if 'xx' in line:
                     Do my thing
                if 'yy' in line:
                     Do my thing etc.

但在标题下方有一个未确定列数和未确定行数的数据块(列数和每列是什么,在标题中指定)。这我无法通过例如 matplotlib 制作图表的方式来阅读。 (我可以通过手动将数据复制到一个单独的文件并将其读取为可绘制的格式来正确处理,但这不是我每次对每个文件都想做的事情......)数据开始之前的行包含非常有用的#eoh,但我想不出一种方法来结合前 50 多行的选择性读取,然后切换到将所有内容读取到数组中。如果有办法以更好的方式做我想做的事(包括选择地图以及查看哪些文件存在且可读),我愿意接受建议。

更新: @ImportanceOfBeingErnest 提出的解决方案似乎非常有用,但我没有让它发挥作用。 所以我将从答案中提到的数据开始。 列名按以下格式给出:

#COLUMNINFO= NUM​​BER1,单位,测量,NUMBER2

在这种格式中,number1 是列号,unit 是测量的单位,measurement 是测量的内容,number2 是测量的数字。 数据由空格分隔,但我怀疑这不会是问题。

我尝试在循环中实现读取标题以确定标题的结尾,这没有任何可见的效果,甚至检查中间结果的打印命令也没有显示。 一旦我将'print line'放在'for line in f:'之后,我想我可以看到出了什么问题,但似乎整个循环都被忽略了,包括由于文件完成读取而导致错误的break命令并且没有数据留待其他部分读取...

任何帮助将不胜感激。

【问题讨论】:

  • 你看过pandas吗?在按列排列数据时可以提供很大帮助,并且非常 matplotlib 友好..

标签: python python-2.7 matplotlib


【解决方案1】:

首先,如果标题在每行的开头有一个特定的字符,这可以用来自动过滤掉标题。使用numpy,您可以使用numpy.loadtxt(filename, delimiter=";", comment="#") 加载数据,并且以# 开头的每一行都将被忽略。 不知道这里是不是这样?!

在您描述的情况下,您有一个标题结束标志#eoh,您可以首先逐行读取标题,以找出您以后需要忽略的行数,然后在加载时使用该数字文件。

我已经组装了一个小例子,它是如何工作的。

def readFile(filename):
    #first find the number of lines to skip in the header
    eoh = 0
    with open(filename, "r") as f:
        for line in f:
            eoh = eoh+1
            if "#eoh" in line:
                break
    # now at this point we need to find out about the column names
    # but as no data is given as example, this is impossible
    columnnames = []            
    # load the file by skipping eoh lines,
    # the rest should be well behaving
    a = np.genfromtxt(filename, skip_header = eoh, delimiter=";" )

    return a, columnnames

def plot(a, columnnames, show=True, save=False, filename="something"):
    fig = plt.figure()
    ax = fig.add_subplot(111)
    # plot the forth column agains the second
    ax.plot(a[:, 1], a[:,3])    
    # if we had some columnname, we could also plot
    # column named "ulf" against the one named "alf"
    #ax.plot(a[:, columnnames.index("alf")], a[:,columnnames.index("ulf")]) 

    #now save and/or show
    if save:
        plt.savefig(filename+".png")
    if show:
        plt.show()


if __name__ == "__main__": 
    fullpath = "path/to/files/file*.txt" # or whatever       
    for filename in glob.glob(fullpath):
        a, columnnames = readFile(filename)
        plot(a, columnnames, show=True, save=False, filename=filename[:-4])

剩下的一个问题是列的名称。由于您没有提供任何示例数据,因此很难估计如何准确地做到这一点。

这一切都假设您之间没有任何缺失数据或任何此类数据。如果是这种情况,那么您需要使用 numpy.genfromtxt() 的所有参数来相应地过滤数据。

【讨论】:

  • 看起来很棒,因为这对我来说是一个副项目,我现在没有时间实施它,但它看起来很有希望。我特别喜欢'def'部分,因为我不知道它或python中存在类似的东西。
猜你喜欢
  • 2012-12-26
  • 2023-03-16
  • 2012-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多