Python读取.txt文件头部

4

我需要从一个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分隔符分开。因此,我可以使用这种安全的方式来拆分字符串。 - brium-brium
4个回答

2

我会使用 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 - brium-brium
我添加了 height = height_line.split('\t')[1],这很好地解决了我的问题。我还使用了一些过滤器,如 height_line.find('\t')math.isnanpanda.isnull(),它们也可以捕获nan和空条目。 - brium-brium

1

这应该可以工作!

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条目甚至是空条目。有没有办法过滤掉它们? - brium-brium
你可以将 value = ... 这一行放在 try/except 块中,这样如果它尝试解析的内容不是数字,except 块就会捕获异常并将 value 设置为 None。然后,在 for 循环完成后,您可以检查 value 是否等于 None。如果不是,则执行正常操作,如果是,则要么什么也不做,要么添加一些逻辑来处理没有指定良好的总高度的文件应该发生什么。此外,如果这个答案回答了你的问题,请给它点赞并标记为正确答案,谢谢 :) - Christopher Shroba

0

这样做可以,但有一个注意事项:

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: 需要多于1个值来解包 - brium-brium
听起来像是在尝试在一行中分割一个不存在的字符(例如 '\t')。我只是猜测\t被使用了。正如我所说,您必须先解决文件格式问题:到底是什么规则将键与值分开?我的答案中的代码必须根据该问题的答案进行调整,而这无法从您的示例中确定。 - jez

0

如果头文件中的键始终相同,您可以使用re模块来完成它:

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

我有相同的任务去读取头文件,并使用re模块完成了它


但这不会限制它只能使用数字作为输入吗?我那里还有字母输入。 - brium-brium
@brium-brium,你可以将([0-9]+)替换为(.+?),这样它就能找到空格后和换行符前的任何字符。 - Greg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接