找到每个时间步长的文本和数字之间的最大值

时间:2016-09-08 13:15:48

标签: python list python-3.x max

我打算在输入数据中找到TS下每行的最大值,以获取非常大的数据。这是输入数据:

SCALAR
ND    3
ST  0
TS        10.00
0.0000
0.0000
0.0000
SCALAR
ND    3
ST  0
TS      3600.47
255.1744
255.0201
257.0000
SCALAR
ND    3
ST  0
TS      7200.42
255.5984
255.4946
255.7014
SCALAR
ND    3
ST  0
TS      10000.0
256.5984
255.1946
255.7014

最后,我想用不同的时间步长保存最大值,如下所示:

SCALAR
ND    3
ST  0
TS      0.00
**256.60**
**255.49**
**257.00**

我写了这样的代码:

 from __future__ import print_function

 lines = []
 Newlist = []
 with open('data.txt') as f, open('output.txt', 'w') as outfile:
     for line in f:
         lines.append(line.rstrip('\n'))
         lines1=list(enumerate(lines))
         list_n=list(zip(*(iter(lines),)*7))
         max_value = max(float(n) for n in list_n)
print(max_value, file=outfile)

程序一直工作到最后一行但是最后一行的执行我得到以下错误:ValueError:max()arg是一个空序列。我不知道为什么。

我应该提一下,我在TS之后删除了很多数字,以使这个例子变小。有许多值必须检查。必须检查每个时间步长(TS)的相同行。

1 个答案:

答案 0 :(得分:2)

你的尝试在几个不同的地方失败了;您已分配给lines1但忽略了这一点,您尝试使用lines列表每次迭代生成max()值,您从未过滤掉非数字行,因此尝试调用float()对那些会失败,你从来没有正确地对数字行进行分组。

如果输入文件太大,我不会使用max()函数,而是在解析文件时跟踪3个最大值,测试每行到目前为止找到的最大值。

只需阅读该文件,直至遇到TS行,然后消耗行,直到有SCALAR行或文件末尾为止;那些是你想要获得最大值的数字,然后你可以写出来到输出文件。

我会尽可能保留格式:

maxima = [[float('-inf'), ''] for _ in range(3)]

with open('data.txt') as f:
    for line in f:
        if line.startswith('TS'):
            # timestamp group, find maximum for the next 3 lines
            for maximum, line in zip(maxima, f):
                value = float(line)
                if value > maximum[0]:
                    maximum[:] = value, line

with open('output.txt', 'w') as outfile:
    # write header to output file
    outfile.write('SCALAR\nND    3\nST  0\nTS      0.00\n')
    # write the 3 maximum lines:
    for value, line in maxima:
        outfile.write(line)

请注意,只要其中一个输入用完,zip()就会停止迭代;首先放maxima,这意味着每次只读取3行。我使用maxima启动了float('-inf')列表,因为根据定义,任何其他浮点值都将被视为大于此值。另外,请注意,不需要删除换行符; float()不关心前导或尾随空格,因此该行忽略行末尾的任何换行符。

以上跟踪最大值为浮点值但保留原始线条;输出文件分别包含256.5984255.4946257.0000,而不是舍入值。

这使您的输出接近原始:

>>> from io import StringIO
>>> sample = StringIO('''\
... SCALAR
... ND    3
... ST  0
... TS        10.00
... 0.0000
... 0.0000
... 0.0000
... SCALAR
... ND    3
... ST  0
... TS      3600.47
... 255.1744
... 255.0201
... 257.0000
... SCALAR
... ND    3
... ST  0
... TS      7200.42
... 255.5984
... 255.4946
... 255.7014
... SCALAR
... ND    3
... ST  0
... TS      10000.0
... 256.5984
... 255.1946
... 255.7014
... ''')
>>> maxima = [[float('-inf'), ''] for _ in range(3)]
>>> with sample as f:
...     for line in f:
...         if line.startswith('TS'):
...             # timestamp group, find maximum for the next 3 lines
...             for maximum, line in zip(maxima, f):
...                 value = float(line)
...                 if value > maximum[0]:
...                     maximum[:] = value, line
...
>>> outfile = StringIO()
>>> outfile.write('SCALAR\nND    3\nST  0\nTS      0.00\n')
34
>>> for value, line in maxima:
...     outfile.write(line)
...
9
9
9
>>> print(outfile.getvalue())
SCALAR
ND    3
ST  0
TS      0.00
256.5984
255.4946
257.0000

如果您确实希望将输出舍入为2位小数,则可以始终使用outfile.write('{:.2f}\n'.format(value))