使用Python v3.5加载制表符分隔文件,省略部分行,输出特定列的最大最小浮点数到新文件

Using Python v3.5 to load a tab-delimited file, omit some rows, and output max and min floating numbers in a specific column to a new file

我已经尝试了几个小时来研究这个问题,但所有可能的解决方案都不适合我的特定需求。 我在 Python (v3.5) 中编写了以下内容以下载制表符分隔的 .txt 文件。

#!/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)

这会下载 the file from here 并根据当前时间重命名。它完美运行。

我希望我可以使用 "filename" 变量来加载文件并对它做一些事情(而不是必须写出完整的文件路径和文件名,因为我的最终目标就是对几百个不同的文件做以下操作,所以在长运行).

中使用变量会更容易

这个使用变量的想法似乎可行,因为将以下内容添加到上面会将文件的内容打印到 STDOUT...(因此它能够毫无问题地找到文件):

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 的单独文件中。

如果有人有任何指点,我将不胜感激。

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

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 文件中累积多个最大值和最小值,因此我在'append' 模式。如果不是这种情况,请将 'a' 参数换成 'w',这样每次都会覆盖文件内容。

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

编辑 2:已更新以解决负数问题,Derek 在单独的回答中也提到了这一点。

这是对你向 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)