我是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)
我使用了此问题initialize a numpy array
中建议的类似代码我的每个文件每4列大约有1500行。我尝试使用 np.mean ,但它不起作用可能是因为我的一些数据是字符串类型。
提前感谢您的帮助!
答案 0 :(得分: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
答案 1 :(得分: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循环中执行此操作,只保存该计算的结果。