【问题标题】:Python read .txt-files headerPython 读取 .txt 文件头
【发布时间】:2016-11-17 18:23:59
【问题描述】:

我需要从 txt 文件头中读取一些信息,如下所示:

Date    20160122
SP Number   8
Gauge   250N internal
Total Height    61
SP Modell   SP2
Corner Distance 150 

Height  Value   Comment
60  NaN 
...

我有一个 python 程序目前正在这样做:

depth, N = npy.loadtxt(filename, skiprows=8, unpack=True, usecols = usecols)

但是我想从标题中读出一些值。有没有办法做到这一点?我最感兴趣的是获得“总高度”的值。在我的搜索中,我似乎只找到了有关 .csv 文件的答案。

【问题讨论】:

  • 标头中的条目由\t 分隔符分隔。所以我可以用它作为一种安全的方式来分割字符串。

标签: python file numpy


【解决方案1】:

我会使用open 而不是npy.loadtxt

with open(filename, 'r') as the_file:
    all_data = [line.strip() for line in the_file.readlines()]
    height_line = all_data[3]
    data = all_data[8:]

然后你可以解析height_line的值,得到总高度。并且文件中的所有数据都将在变量data 中。

【讨论】:

  • 如何解析它以及如何从data 中获取Ndepth 的值?
  • 我添加了height = height_line.split('\t')[1],这很好地解决了我的问题。我还添加了一些带有height_line.find('\t')math.isnanpanda.isnull() 的过滤器,它还可以捕获nans 和空条目。
【解决方案2】:

这应该可行!

field = "Total Height"

# Get first 6 lines
with open(filename) as file:
    lines = [next(file) for x in range(6)]

value = None
for line in lines:
    if line.startswith(field):
        # Get the part of the string after the field name
        end_of_string = line[len(field):]

        # Convert it to an int:
        value = int(end_of_string.strip())

print(value) #Should print 61

如果您知道字段名称和值由制表符而不是空格分隔,则可以改用line.split('\t') 将每一行分成字段名称和字段值,然后检查 field_name 是否为字段你关心的是,如果是的话,使用该值,而不是使用startswith,然后对结果字符串进行切片以获得它的结尾。

【讨论】:

  • 它有效。我只有一个问题,一些文件有一个NaN 条目,甚至是一个空条目。有办法过滤吗?
  • 您可以将 value = ... 行放在 try/except 块中,这样如果它尝试解析不是数字的内容,则 except 块会捕获异常并将 value 设置为 None .然后,在 for 循环完成后,您可以检查 value 是否等于 None。如果没有,请执行正常操作,如果是,则不执行任何操作或添加一些逻辑,以说明如果文件没有指定好的总高度应该发生的情况。另外,如果此答案回答了您的问题,您介意对其进行投票并将其标记为正确吗? :)
【解决方案3】:

这样做可以,但有一个警告:

import numpy as npy

usecols = (0, 1)

header = {}
with open(filename, 'rt') as f:
    for header_lines, line in enumerate(f):
        line = line.strip()
        if not line: break # assume that a blank line means "header stops here"
        key, value = line.split(' ', 1)
        header[key] = value


depth, N = npy.loadtxt(filename, skiprows=header_lines + 2, unpack=True, usecols=usecols)

问题在于标头格式在什么是键和什么是值方面存在歧义。一些键似乎是多个以空格分隔的单词,而一些值也是,但是(不确定的数量)空格也是显然是将键与值分开的唯一规则。在大多数情况下,键和值之间有 3 个空格,但 Corner Distance 后面只有 1 个空格,因此它是模棱两可的(除了人脑自己复杂的上下文解析器)键结束和值开始的位置。

也许问题只是对真正应该是标签的内容进行了糟糕的渲染(在此页面上,或在复制粘贴到 SO 的过程中)。如果是这样,

        key, value = line.split('\t', 1)

将解决问题。但如果不是,则需要先解决文件格式的歧义,然后才能编写明确的解决方案。

【讨论】:

  • 这样我得到:ValueError: need more than 1 value to unpack
  • 听起来像是试图在一个字符(例如'\t')上拆分一行,而该字符没有出现在该行中。我只是猜测\t 正在被使用。正如我所说,在继续之前您必须解决文件格式的一些问题:将键与值分开的规则是什么?我的答案中的代码必须根据该问题的答案进行调整,这无法从您的示例中确定。
【解决方案4】:

你可以用re模块来做,如果头文件中的键总是相同的:

file = open(filename, 'r')
data = file.read()
Total = re.findall( 'Total Height\s*([0-9]+)\s*\n', data)[0]

我有同样的任务来读取头文件和did itre 模块

【讨论】:

  • 但这不是将其限制为数字作为条目吗?我那里也有信件条目。
  • @brium-brium 你可以用(.+?)替换([0-9]+),它会在空格之后和换行符之前找到任何字符
猜你喜欢
  • 2016-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多