Эффективная обработка большого файла.txt в python

Я довольно плохо знаком с Python и программированием в целом, но я пытаюсь выполнить вычисление "скользящего окна" для файла.txt с разделителями табуляции, который содержит около 7 миллионов строк с Python. Под скользящим окном я подразумеваю, что оно будет выполнять вычисления, скажем, 50 000 строк, сообщать о числе, а затем двигаться вверх, скажем, 10 000 строк, и выполнять те же вычисления еще для 50 000 строк. У меня есть расчеты и "скользящее окно", работающее правильно, и оно работает хорошо, если я проверяю его на небольшом подмножестве моих данных. Однако, если я пытаюсь запустить программу по всему набору данных, она невероятно медленная (у меня она работает уже около 40 часов). Математика довольно проста, поэтому я не думаю, что это займет много времени.

Прямо сейчас я читаю свой файл.txt с помощью модуля csv.DictReader. Мой код выглядит следующим образом:

file1='/Users/Shared/SmallSetbee.txt'
newfile=open(file1, 'rb')
reader=csv.DictReader((line.replace('\0','') for line in newfile), delimiter="\t")

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

Поскольку меня интересует только выполнение моих вычислений по "фрагментам" или "окнам" данных за один раз, существует ли более эффективный способ считывать только указанные строки за раз, выполнять вычисления, а затем повторять с новым указанным " кусок "или" окно "указанных строк?

2 ответа

collections.deque это упорядоченная коллекция предметов, которые могут иметь максимальный размер. Когда вы добавляете предмет к одному концу, один падает с другого конца. Это означает, что для перебора "окна" на вашем CSV, вам просто нужно продолжать добавлять строки в deque и он справится с выбрасыванием полных уже.

dq = collections.deque(maxlen=50000)
with open(...) as csv_file:
    reader = csv.DictReader((line.replace("\0", "") for line in csv_file), delimiter="\t")

    # initial fill
    for _ in range(50000):
        dq.append(reader.next())

    # repeated compute
    try:
        while 1:
            compute(dq)
            for _ in range(10000):
                dq.append(reader.next())
    except StopIteration:
            compute(dq)

Не использовать csv.DictReaderвместо csv.reader, Создание словаря для каждой строки занимает больше времени, чем создание списка для каждой строки. Кроме того, доступ к списку по индексу немного быстрее, чем к словарю по ключу.

Я рассчитал итерацию более 300000 строк 4-колоночного CSV-файла, используя два считывателя CSV. csv.DictReader заняло в семь раз больше, чем csv.reader,

Объедините это с предложением katrielalex использовать collections.deque и вы должны увидеть хорошее ускорение.

Кроме того, профилируйте свой код, чтобы точно определить, где вы проводите большую часть своего времени.

Другие вопросы по тегам