2016-03-08 28 views
0

我试了几个小时来研究这个问题,但是每个可能的解决方案并不适合我的特殊需求。 我在Python(v3.5)中编写了以下内容以下载制表符分隔的.txt文件。使用Python v3.5加载制表符分隔文件,省略一些行,并将特定列中的最大和最小浮点数输出到新文件

#!/usr/bin/env /Library/Frameworks/Python.framework/Versions/3.5/bin/python3.5 
import urllib.request 
import time 
timestr = time.strftime("%Y-%m-%d %H-%M-%S") 
filename="/data examples/"+ "ace-magnetometer-" + timestr + '.txt' 
urllib.request.urlretrieve('http://services.swpc.noaa.gov/text/ace-magnetometer.txt', filename=filename) 

This downloads the file from here and renames it based on the current time。它完美的作品。

我希望我可以使用“文件名”变量然后加载文件并做一些事情(而不是写出完整的文件路径和文件名,因为我的最终目标是做以下几百个不同的文件,所以长期使用变量会更容易)。

这使用最可变想法似乎工作,因为添加以下上面打印文件输出到标准输出的内容......(所以它能够找到该文件没有任何问题):

import csv 
with open(filename, 'r') as f: 
    reader = csv.reader(f, dialect='excel', delimiter='\t') 
    for row in reader: 
      print(row) 

the file可以看出,前18行是信息性的。 第19行提供了实际的列名称。然后是一行破折号。

的实际数据我很感兴趣,开始在线21

我想找到(右第三列),在“BT”列中的最小和最大数字。我发现的一种可能的解决方案只能用于整数,而这个数据集具有浮点数。

另一种可能的解决方案涉及导入pyexcel模块,但我似乎无法正确安装...

import pyexcel as pe 
data = pe.load(filename, name_columns_by_row=19) 
min(data.column["Bt"]) 

我希望能够在最小的BT和最大的Bt值打印成两个单独的文件,称为minBt.txt和maxBt.txt。

我希望任何人有任何指示,请。

回答

1

只要所有文件以相同的方式格式化,即数据21行,相同列数等等,以下操作将起作用。此外,您链接的文件似乎没有制表符分隔,因此我只是在每行上使用字符串split而不是csv阅读器。列从文件到列表读取,并将该列表用于计算的最大值和最小值:

from itertools import islice 

# Line that data starts from, zero-indexed. 
START_LINE = 20 
# The column containing the data in question, zero-indexed. 
DATA_COL = 10 
# The value present when a measurement failed. 
FAILED_MEASUREMENT = '-999.9' 

with open('data.txt', 'r') as f: 

    bt_values = [] 

    for val in (row.split()[DATA_COL] for row in islice(f, START_LINE, None)): 

     if val != FAILED_MEASUREMENT: 
      bt_values.append(float(val)) 

    min_bt = min(bt_values) 
    max_bt = max(bt_values) 

with open('minBt.txt', 'a') as minFile: 
    print(min_bt, file=minFile) 

with open('maxBt.txt', 'a') as maxFile: 
    print(max_bt, file=maxFile) 

我假设,因为你这样做是为了多个文件,你正在寻找累积多个最大和maxBt.txtminBt.txt文件中的最小值,因此我已经以“附加”模式打开它们。如果不是这种情况,请换出'w''a'参数,每次覆盖文件内容。

编辑:已更新以包含失败测量的解决方法,如评论中所述。

编辑2:已更新为解决负数的问题,也由Derek在单独的答案中提到。

+0

那完美。谢谢,Apoc! :) – ZPMMaker

+0

好的,下一个问题,如果你不介意请...有时传感器无法进行测量(因此创建我正在下载的文件的系统改为在该列中输入-999.9。是否有在搜索min_bt值之前过滤出所有等于-999.9的值的方法?再次感谢您的帮助。:) – ZPMMaker

+0

好的,我已经更新了答案,以包含解决方法。它只会添加列中的值,如果它们不等于'-999.9'。 – Apoc

2

这是为了对Apoc的最新问题发表评论,但我是新手,所以我不允许发表评论。有一件事可能会造成问题,bz_values(和bt_values,就此而言)可能是一个字符串列表(至少是我试图在链接的示例文件上运行Apoc脚本时)。你可以代位解决这个问题:

min_bz = min([float(x) for x in bz_values]) 
max_bz = max([float(x) for x in bz_values]) 

min_bz = min(bz_values) 
max_bz = max(bz_values) 
+0

感谢您的建议,Derek。我给了它一个旋风,但提出了以下错误: “minFile.write(min_bz) TypeError:write()参数必须是str,而不是float” (对于上下文,这是我们第一行时尝试将min_bz值写入文件) '带有打开('/ data examples/minBz.txt','w')minFile: minFile。写(min_bz)' (在接下来的评论待续...) – ZPMMaker

+0

...我也改为设法: 'min_bz = MIN([STR(X)为X在bz_values]) max_bz = MAX([ str(x)for x in bz_values])' 但是刚刚将-0.1打印到minBz文件中。 对于如何解决'TypeError:write()参数必须是str,而不是float',你有什么建议吗? 再次感谢您的帮助。 – ZPMMaker

+0

你完全正确的德里克,它以前是按字母顺序计算最小 - 最大值(我的一个疏忽)。我已经更新了我的答案,使它能够与浮动(并因此为负值)一起工作。此外,TypeError的原因是'write'方法只接受字符串,在你的例子中'min_bz'和'max_bz'都是浮点数。而不是进行另一种类型转换,我转而使用'print'函数来避免这种情况。 – Apoc

相关问题