2016-03-08 35 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

相關問題