Как я могу эффективно открыть 30 ГБ файла и обработать его части без замедления? - PullRequest
5 голосов
/ 23 апреля 2019

У меня есть несколько больших файлов (более 30 ГБ) с фрагментами информации, по которым мне нужно провести некоторые вычисления, например, усреднение.Куски, которые я упоминаю, представляют собой фрагменты файла, и я знаю номера строк начала и количество последующих строк для каждого фрагмента.

Итак, у меня есть словарь с ключами в качестве начальных номеров строк и значениями в виде количества следующих строк, и я использую этот словарь для циклического перемещения по файлу и получения фрагментов по нему.для каждого среза я создаю таблицу, делаю некоторые преобразования и усреднения, создаю новую таблицу и преобразую ее в словарь.Я использую islice для нарезки и pandas dataframe для создания таблиц из каждого среза.

однако, со временем процесс становится все медленнее и медленнее, даже размер кусочков более или менее одинаков.Первые 1k срезов - обработаны за 1 час. Вторые 1k срезов - обработаны за 4 часа. Третьи 1k срезов - обработаны за 8 часов. Вторые 1k срезов - обработаны за 17 часов.

Сейчас я делаю это на компьютере с Windows 10, 1 ТБ SSD, 32 ГБ оперативной памяти.Ранее я также пробовал на Linux-машине (Ubuntu 18.4) с 250 ГБ SSD и 8 ГБ оперативной памяти + 8 ГБ виртуальной памяти.Оба результата более или менее одинаковы.

В Windows я заметил, что используется 17% ЦП и 11% памяти, но использование диска составляет 100%.Я не до конца знаю, что означает дискус, и как я могу его улучшить.

Как часть кода, я также импортировал данные в mongodb, работая над linux, и подумал, что это может быть из-за индексации в mongodb.но когда я печатал время обработки и время импорта, я заметил, что почти все время уходит на обработку, импорт занимает несколько секунд.
Кроме того, чтобы выиграть время, я сейчас выполняю часть обработки на более сильной машине с Windows и пишу документыкак текстовые файлы.Я ожидаю, что запись на диск немного замедлит процесс, но размеры текстовых файлов не превышают 600 КБ.

Ниже приведен фрагмент кода, как я читаю файл:

with open(infile) as inp:
    for i in range(0,len(seg_ids)): 
        inp.seek(0)
        segment_slice = islice(inp,list(seg_ids.keys())[i], (list(seg_ids.keys())[i]+list(seg_ids.values())[i]+1)) 
        segment = list(segment_slice)

        for _, line in enumerate(segment[1:]):
            #create dataframe and perform calculations

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

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

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

1 Ответ

0 голосов
/ 23 апреля 2019

Несколько вещей приходят на ум.

Во-первых, если вы перенесете данные в DataFrame pandas, для импорта больших данных будет аргумент 'chunksize'.Это позволяет вам обрабатывать / сбрасывать то, что вам нужно / не нужно, при этом проверяя информацию, такую ​​как df.describe, которая даст вам сводную статистику.

Кроме того, я слышу замечательные вещи о dask .Это масштабируемая платформа с параллельной, многоядерной, многопользовательской обработкой, и она почти так же проста, как использование панд и numpy с очень небольшим управлением требуемыми ресурсами.

...