2013-07-19 3 views
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 файлах. Поэтому меня интересует только среднее значение для каждого элемента в 100 файлах для столбца 3.

Кроме того, хотя код в вопросе 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

Каждый из моих файлов будет в около 1500 строк на 4 колонки. Я попытался использовать np.mean, но это не работает, вероятно, потому что некоторые из моих данных являются строковыми.

Заранее благодарим за вашу помощь!

+1

Чтобы все элементы были численными, попробуйте использовать карту, например. allDouble = map (lambda el: float (el), mixedTypeArray). Кроме того, не устанавливайте dtype как str, если вы хотите, чтобы они были числовыми. –

+0

Спасибо!Если я не устанавливаю dtype на str, я получаю следующее сообщение об ошибке: ** ValueError: невозможно преобразовать строку в float: Transposon Inactive **. Как использовать эту функцию карты ... Я не понял, что вы имеете в виду (извините). – Fabs

+0

Вам нужна четвертая колонка? Если вы не видите мой ответ ниже. map - полезная функция, которая позволяет применять функцию к каждому члену массива. 'Lambda' определяет функцию внутри функции карты. Это эквивалентно 'def toFloat (num): float (num); map (toFloat, arrayToBeConverted) '. Потребуется некоторое время, чтобы привыкнуть, но очень полезно, когда вы его получите. –

ответ

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 
+0

Спасибо! Я пробовал свой код, и я получаю следующее сообщение об ошибке ** IndexError: слишком много индексов **. Я понятия не имею, что это может быть. Какие-либо предложения? – Fabs

+0

Да, произошла ошибка. 'np.genfromtxt' возвращает структурированный массив, который является одномерным, а не двумерным. Таким образом, вы получите третий столбец с 'arr ['f2']', а не 'arr [:, 2]'. (Столбец или имена полей являются метками 'f0',' f1' и т. Д. По умолчанию.). – unutbu

+0

Спасибо! Теперь это сработало. Я также пробовал эту версию, используя np.mean, и он также работает. Я не знал об этом «f1» и т. Д. :) Итак, если я хочу написать информацию обо всех остальных столбцах, я должен просто зациклиться один раз в одном из файлов и скопировать информацию о столбцах 1, 2 и 4 в другой файл txt и добавить эту среднюю переменную «средние» в качестве третьего столбца? Не знаю, как это сделать, но я постараюсь выяснить! :) – Fabs

0

Там другое ключевое слово аргумент в np.loadtxt: usecols. Попробуйте использовать это, например.

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

Вам не нужно np.array так np.importtxt возвращает ndarray. Я пропустил dtype = str, потому что по умолчанию это dtype = float, что должно сделать все для вас, если вы хотите вычислить среднее значение.

Кроме того, вместо создания массива массивов, если вы просто хотите вычислить среднее значение в каждом файле, я предлагаю вам сделать это в цикле for и просто сохранить результат этого вычисления.

Смежные вопросы