2016-05-09 3 views
2

Я новичок в Python. У меня есть 10 входных файлов в формате, показанном ниже. Каждый файл содержит данные измерений для приемника (приемники 1-10). Каждый приемник имеет измерения от 10 передатчиков (передатчики 1-10). Файлы упорядочены хронологически со временем в секундах.Python-Как читать несколько файлов одновременно и вести записи данных

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

Я не могу загрузить эти файлы в память, потому что файлы огромны (порядка гигабайт). Сохранение всех усредненных значений в памяти также является проблемой из-за размера файлов. Я хочу сохранить данные о часах для каждой пары приемник-передатчик для усредненных значений в памяти. Как только у меня будет значение усредненных значений часа, когда вычисляется новое усредненное значение, я хочу отказаться от самого старого.

Я думал, что словари могут быть лучшим способом отслеживать данные.

Как я могу выполнить задачу выше?

входного файла:

Колонка Формат: Время (в секундах) Передатчик # Измерение

0.0 1 2.4779E+02 
0.0 2 2.8147E+02 
0.0 3 2.7437E+02 
0.0 4 2.6661E+02 
0.0 5 2.2637E+02 
0.0 6 2.1457E+02 
0.0 7 2.3750E+02 
0.0 8 2.9573E+02 
0.0 9 2.7339E+02 
0.0 10 2.4982E+02 
1.0 1 2.1086E+02 
1.0 2 2.7459E+02 
1.0 3 2.1569E+02 
1.0 4 2.0018E+02 
1.0 5 2.8732E+02 
1.0 6 2.2633E+02 
1.0 7 2.2900E+02 
1.0 8 2.6883E+02 
1.0 9 2.4482E+02 
1.0 10 2.8314E+02 
2.0 1 2.6987E+02 
2.0 2 2.5946E+02 
2.0 3 2.8195E+02 
2.0 4 2.3097E+02 
2.0 5 2.2592E+02 
2.0 6 2.5316E+02 
2.0 7 2.5562E+02 
2.0 8 2.5892E+02 
2.0 9 2.1258E+02 
2.0 10 2.5791E+02 
+1

Что вы _tried_ до сих пор? Не беспокойтесь о загрузке файлов в память: 'open()' Python создает интерфейс _streaming_ файла, поэтому вы читаете только одну строку файла в памяти за раз с помощью 'readline()' (и автоматически удаляете то, что было раньше), а не все сразу (хотя вы можете заставить его сразу все это прочитать). Ваша основная проблема уже решена, поэтому ничто не мешает вам делать это так, как вы хотите использовать наивный подход. –

+0

@markm, если у вас есть ответ, отметьте его и закройте, так как это поможет другим участникам. Благодарю. –

ответ

2

Вы можете использовали FileObject.readline() в Python, чтобы получить доступ к файлам паралельно.

#!/usr/bin/python 

# Open a file 
fo = open("foo.txt", "rw+") 
fo1 = open("foo1.txt", "rw+") 

line = fo.readline() 
print "Read Line from foo: %s" % (line) 

line = fo1.readline() 
print "Read Line from foo1: %s" % (line) 

# Close opend file 
fo.close() 
fo1.close() 

Аналогичным образом вы можете использовать 10 объектов для 10 различных входных файлов и использовать readline для каждого из них. Надеюсь это поможет.

Для описания проблемы вы можете прочитать измерения из каждого файла для каждого передатчика и усреднить эти значения для получения усредненного значения в 4 секунды на пару приемника-передатчика. Чтобы отслеживать каждое усредненное значение для каждой пары приемник-передатчик, создайте словарь или пользовательский список. Затем создайте свою логику для получателя, чтобы получить окончательный результат/значение. Но убедитесь, что вы удаляете данные из словаря/списка, когда они больше не нужны. Надеюсь, это поможет.

1

Ряд объектов Python поможет:

  • положить образцы в defaultdict, где каждый элемент является списком, шпонкой на передатчике ID
  • использования glob перечислить все файлы данных в ваш каталог
  • с namedtuple с мы можем дать каждому биту данных имя, которое легче читать, чем простой список или кортеж

открывать файлы данных в параллельном, магазин каждого передатчика список образцов

#!/usr/bin/env python 

''' 
averagetrans -- calculate receiver/transmitter averages 
''' 
import collections 
import glob 
import sys 

ReceiverData = collections.namedtuple(
    'ReceiverData', 
    ['path', 'time_sec', 'transmitter', 'measurement']) 

def parse_data(path, line): 
    words = line.rstrip().split() 
    return ReceiverData(
     path=path, 
     time_sec=words[0], 
     transmitter=words[1], 
     measurement=float(words[2])) 


transmitter_data = collections.defaultdict(list) 

files = dict((path, open(path)) 
      for path in glob.glob('receiver*.csv')) 

while True: 
    for rpath, rfile in files.iteritems(): 
     line = rfile.readline() 
     if not line: 
      sys.exit(0) 
     datum = parse_data(rpath, line) 

     cur_data = transmitter_data[datum.transmitter] 
     # take most recent four samples 
     cur_data.append(datum) 
     cur_data = cur_data[-4:] 

     average = sum(dat.measurement for dat in cur_data)/len(cur_data) 

     print 'trans {}: average {}'.format(
       datum.transmitter, 
      average) 
     # print '\t- data: {}'.format(cur_data) 

выход с каждого передатчика 4-средняя выборочная

trans 4: average 200.18 
trans 1: average 247.79 
trans 5: average 287.32 
trans 2: average 281.47 
trans 6: average 226.33 
trans 3: average 274.37 
trans 7: average 229.0 
trans 4: average 233.395 
trans 8: average 268.83 
trans 5: average 256.845 
trans 9: average 244.82 
trans 6: average 220.45 
trans 10: average 283.14 
trans 7: average 233.25 
trans 1: average 258.83 
trans 8: average 282.28 
trans 2: average 270.465 
trans 9: average 259.105 
trans 3: average 278.16 
trans 10: average 266.48 
trans 4: average 232.586666667 
trans 1: average 242.84 
trans 5: average 246.536666667 
trans 2: average 271.84 
trans 6: average 231.353333333 
trans 3: average 257.336666667 
trans 7: average 240.706666667