2016-09-07 135 views
0

我想学习Python,我有意使一个非常大的数据文件变小,后来做一些统计分析与R我需要读取数据文件(见下文):小数点后阅读完整的数据文件和整数到2位小数,并保存为相同的格式

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 
255.2748 
SCALAR 
ND 3 
ST 0 
TS  7200.42 
255.5984 
255.4946 
255.7014 

,并找到号码和圆形它在两位数,svae在TS前面的类别数的最大数量。在最后保存相同格式的数据文件类似以下内容:

SCALAR 
ND 3 
ST 0 
TS  10.00 
0.00 
0.00 
0.00 
SCALAR 
ND 3 
ST 0 
TS  3600.47 
255.17 
255.02 
255.27 
SCALAR 
ND 3 
ST 0 
TS**MAX**  7200.42 
255.60 
255.49 
255.70 

我写这样的代码:

import numpy as np 
import matplotlib.pyplot as plt 
import pickle 

# Open file 
f = open('data.txt', 'r') 
thefile = open('output.txt', 'wb') 
# Read and ignore header lines 
header1 = f.readline() 
header2 = f.readline() 
header3 = f.readline() 
header4 = f.readline() 
data = [] 
for line in f: 
    line = line.strip() 
    columns = line.split() 
    source = {} 
    source['WSP'] = columns[0] 
    #source['timestep'] = float(columns[1]) 
    source['timestep'] = columns[1] 
    data.append(source) 

f.close() 

但在TS前面的数字不能被读取。我想整理这些数字,但是我使用的浮点数不起作用。之后,我想把它放在一个循环中任何建议,我是否以良好的方式编写代码?我会非常感谢帮助。

回答

1

第一部分可以很容易地做,如果可以假设的是需要四舍五入的彩车只发生在:你可以先试着在每件行转换为浮动,而忽略它,如果它失败处理与线路本身。这不包括以alpha字符为前缀的行,例如TS 3600.47

from __future__ import print_function 

with open('data.txt') as f, open('output.txt', 'w') as outfile: 
    for line in (l.rstrip() for l in f): 
     try: 
      print('{:.2f}'.format(float(line)), file=outfile) 
     except ValueError: 
      print(line, file=outfile) 

第二部分,但是,需要的是,文件以其整体被缓冲,因为它不是已知的,其中用于TS的最大值将是 - 它可以是在文件的开始时,在端部,或之间的任何地方。下面是一些代码来做到这一点:

from __future__ import print_function 

with open('data.txt') as f, open('output.txt', 'w') as outfile: 
    lines = [] 
    max_ts = 0 
    max_ts_idx = None 

    for i, line in enumerate(l.rstrip() for l in f): 
     try: 
      lines.append('{:.2f}'.format(float(line))) 
     except ValueError: 
      if line.startswith('TS'): 
       new_ts = float(line.split()[-1]) 
       if new_ts > max_ts: 
        max_ts = new_ts 
        max_ts_idx = i 
      lines.append(line) 

    for i, line in enumerate(lines): 
     if i == max_ts_idx: 
      line = line.replace('TS', 'TS**MAX**') 
     print(line, file=outfile) 

它基本上是一样的只打印版本以上,然而,线目前已累计到列表lines。 “TS”行的最大值保存在max_tsmax_ts_idx中该“TS”行的相应行号中。最后,lines列表被迭代并将行写入文件。如果该行包含“TS”的最大值(由max_ts_idx确定),则该行用**MAX**修饰。

+0

非常感谢。我真的走错了方向。你能否给我一个提示以下问题。我试图重写rpogram,但它并没有给我正确的答案。我还希望在TS中找到所有第一个号码,第二个号码,第三个号码,第四个号码等等之间的最大数量...... –

1

尝试"%.2f" % float(columns[1])四舍五入到小数点后两位。请注意,它给你一个字符串,而不是一个浮点数。我不明白你问的其余部分。

>>> "%.2f" % 255.5984
'255.60'

1

代码不正确执行(其中选择最多NUM或保存到输出或...), 请把固定一个, 但如果你有唯一的麻烦浮动功能,您可以选择%.2f或圆形(NUM,2)

1

下面是一些浮点转换成字符串2位小数与format语法(新python2/3格式化语法):

"{:.2f}".format(some_float) 

关于您的其余问题:您的代码似乎不能正确处理您的文本文件的格式。你必须注意这样一个事实,即在每一行上都可以是:只有文本,文本和数字,或者只有一个数字。

out=[] 
for column in columns : 
    try: 
     out.append("{:.2f}".format(float(column))) 
    except ValueError: 
     out.append(column)