2016-09-08 56 views
0

我打算在非常大的數據的輸入數據中找到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)的同一行。

回答

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行。我使用float('-inf')開始了maxima列表,因爲根據定義,任何其他浮點值都將被視爲大於此值。另外請注意,不需要去掉換行符; 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 

你總是可以使用outfile.write('{:.2f}\n'.format(value))相反,如果你真的想有輸出四捨五入到2位小數。

+0

@MohamadRezaSalehiSadaghiani:你的意思是行數可以改變?你知道當你打開一個文件時有多少行嗎?如果不是,那麼行數總是相同的? –

+0

是的。但我用另一個循環和count +函數解決了它。 –

+0

你能給我一個提示,我怎麼能得到最大值的行數?我想找到這一行並打開另一個文件並讀取第二個文件的兩個值並寫入一個新的數據! –

相關問題