2

我对 Python 很陌生,我也进行了很多搜索以找到与我类似的问题。我想做一些类似于这个问题中解释的事情 Computing averages of records from multiple files with python

但是,我不想取每个值的平均值(如本例中所有值都是数字),我想取单个列的平均值,但保留其他列的所有相同值“

例如:

fileA.txt:  
0.003 0.0003 3 Active   
0.003 0.0004 1 Active  

fileB.txt:  
0.003 0.0003 1 Active   
0.003 0.0004 5 Active  

我想生成以下输出文件

output.txt
0.003 0.0003 2 Active   
0.003 0.0004 3 Active

尽管第 1 列和第 2 列也是数字,但对于 100 个文件的相同位置,它们将是相同的值。所以我只对第 3 列 100 个文件中每个元素的平均值感兴趣。

此外,尽管问题Computing averages of records from multiple files with python中的代码适用于读取我的文件。如果您有很多文件,它就没有用。我该如何优化呢?

我设法使用以下代码读取我的文件:

import numpy as np

result = []
for i in my_files:
    a = np.array(np.loadtxt(i, dtype = str, delimiter = '\t', skiprows = 1))
    result.append(a)
result = np.array(result)

我使用了这个问题中建议的类似代码初始化一个numpy数组

我的每个文件每 4 列大约有 1500 行。我尝试使用np.mean但它不起作用可能是因为我的一些数据是字符串类型。

在此先感谢您的帮助!

4

2 回答 2

1

如果您使用 加载数组np.genfromtxt(..., dtype=None)genfromtxt则将猜测每列的 dtype。例如,第三列将被赋予一个整数 dtype。这将使您的数组适合算术。在字符串数组中使用dtype='str'结果,这不适合算术。


import csv
import numpy as np
import itertools as IT
my_files = ['fileA.txt', 'fileB.txt']

vals = None
for num, filename in enumerate(my_files, 1):
    arr = np.genfromtxt(filename, dtype=None, delimiter='\t', skiprows=1, usecols=(2,))
    print(arr)
    if vals is None:
        vals = arr
    else:
        vals += arr

meanvals = vals / num

with open(my_files[0], 'rb') as fin, open('/tmp/test.csv', 'wb') as fout:
    # skip first row
    next(fin)
    writer = csv.writer(fout, delimiter='\t', lineterminator='\n')
    for row, val in IT.izip(csv.reader(fin, delimiter='\t'), meanvals):
        row[2] = val
        writer.writerow(row)

结果,/tmp/test.csv看起来像这样:

0.003   0.0003  2   Active
0.003   0.0004  3   Active
于 2013-07-19T18:17:27.073 回答
0

np.loadtxt 中还有另一个关键字 arg: usecols。尝试使用它,例如

a = np.loadtxt(i, usecols = (0,1,2), delimiter = '\t', skiprows = 1)

您不需要 np.array,因为 np.importtxt 返回一个 ndarray。我省略了 dtype=str,因为默认值是 dtype=float,如果你想计算平均值,这对你来说应该没问题。

此外,如果您只想计算每个文件中的平均值,而不是创建数组数组,我建议您在 for 循环中执行此操作并保存该计算的结果。

于 2013-07-19T18:49:55.763 回答