计算时排除-1

时间:2017-07-21 20:12:20

标签: python python-3.x

我有一个非常大的制表符分隔值10000+值的文件。我试图找到数据中每行的平均值,并将这些新值附加到新文件。但是,未找到的值在大文件中输入为-1。在计算平均值时使用-1值会弄乱我的数据。我该如何排除这些值? 大文件结构如下所示:

"HsaEX0029886"  100 -1  -1  100 100 100 100 100 100 -1  100 -1  100
"HsaEX0029895"  100 100 91.49   100 100 100 100 100 97.87   95.29   100 100 93.33
"HsaEX0029923"  0   0   0   -1  0   0   0   0   0   9.09    0   5.26    0

在我的代码中我采用最后3个元素并找到3个值的平均值。如果行中的最后3个元素是85,12和-1,我需要返回85和12的平均值。这是我的整个代码:

with open("PSI_Datatxt.txt", 'rt') as data:
    next(data)
    lis = [line.strip("\n").split("\t") for line in data]        # create a list of lists(each row)
for row in lis:
    x = float(row[11])
    y = float(row[12])
    z = float(row[13])
    avrg = ((x + y + z) / 3)
    with open("DataEditted","a+") as newdata:
        if avrg == -1:
            continue    #skipping lines where all 3 values are -1
        else:
            newdata.write(str(avrg) + ' ' + '\n')

感谢。评论是否需要澄清。

3 个答案:

答案 0 :(得分:1)

   data = [float(x) for x in row[1:] if float(x) > -1]
   if data:
      avg = sum(data)/len(data)
   else:
      avg = 0 # or throw an exception; you had a row of all -1's

第一行是一个相当标准的Pythonism ...给定一个数组(在本例中为row),你可以遍历列表并通过在条件位中使用for x in数组来过滤掉东西。

如果您只想查看最后三个值,根据前三个词的含义,您有两个选项:

data = [float(x) for x in row[-3:] if float(x) > -1]

将查看最后3个,并根据它们是否为-1给出0到3的值。

data = [float(x) for x in row[1:] if float(x) > -1][:-3]

最后会给你3个好的"值(如果给定行的全部或几乎全部为-1,则它将小于3)

答案 1 :(得分:1)

这是与原始问题的格式相同。如果行全为零,它可以让您编写错误消息,或者您可以忽略它而不写任何内容

with open("PSI_Datatxt.txt", 'r') as data:
    for row in data:
        vals = [float(val) for val in row[1:] if float(val) != -1]
        with open("DataEditted","a+") as newdata:
            try:
                newdata.write(str(sum(vals)/len(vals)) + ' ' + '\n')
            except ZeroDivisionError:
                newdata.write("My Error Message Here\n")

答案 2 :(得分:1)

这应该这样做

import csv


def average(L):
    L = [i for i in map(float, L) if i != -1]
    if not L: return None
    return sum(L)/len(L)


with open('path/to/input/file') as infile, open('path/to/output/file', 'w') as fout:
    outfile = csv.writer(fout, delimiter='\t')
    for name, *vals in csv.reader(infile, delimiter='\t'):
        outfile.writerow((name, average(vals))