У меня есть проблема, которую я не смог решить. У меня есть 4 .txt
файлы каждый между 30-70 ГБ. Каждый файл содержит n-граммовые записи следующим образом:
blabla1/blabla2/blabla3
word1/word2/word3
...
Я пытаюсь подсчитать, сколько раз появляется каждый элемент, и сохранить эти данные в новом файле, например:
blabla1/blabla2/blabla3 : 1
word1/word2/word3 : 3
...
До сих пор я пытался просто сохранить все записи в словаре и сосчитать их, т.е.
entry_count_dict = defaultdict(int)
with open(file) as f:
for line in f:
entry_count_dict[line] += 1
Однако, используя этот метод, я сталкиваюсь с ошибками памяти (у меня доступно 8 ГБ ОЗУ). Данные следуют распределению по Зипфиану, например большинство предметов встречаются только один или два раза.
Общее количество записей неясно, но (очень) приблизительная оценка состоит в том, что всего около 15 000 000 записей.
В дополнение к этому я пробовал h5py
, где все записи сохраняются в виде набора данных h5py, содержащего массив [1]
, который затем обновляется, например:
import h5py
import numpy as np
entry_count_dict = h5py.File(filename)
with open(file) as f:
for line in f:
if line in entry_count_dict:
entry_count_file[line][0] += 1
else:
entry_count_file.create_dataset(line,
data=np.array([1]),
compression="lzf")
Однако этот метод является медленным. Скорость записи становится все медленнее и медленнее. Таким образом, если скорость записи не может быть увеличена, такой подход неправдоподобен. Кроме того, обработка данных в чанках и открытие / закрытие файла h5py для каждого чанка не показали существенной разницы в скорости обработки.
Я думал о сохранении записей, которые начинаются с определенных букв, в отдельных файлах, то есть все записи, которые начинаются с a
, сохраняются в a.txt
и т. Д. (Это можно сделать, используя defaultdic(int)
) ,
Однако для этого файл должен повторяться один раз для каждой буквы, что неправдоподобно, учитывая размеры файла (макс. = 69 ГБ).
Возможно, перебирая файл, можно открыть соленье и сохранить запись в диктовке, а затем закрыть солку. Но выполнение этого для каждого элемента значительно замедляет процесс из-за времени, которое требуется для открытия, загрузки и закрытия файла pickle.
Одним из способов решения этой проблемы будет сортировка всех записей за один проход, затем итерация по отсортированному файлу и подсчет записей в алфавитном порядке. Однако даже сортировка файла кропотливо выполняется с помощью команды linux:
sort file.txt > sorted_file.txt
И я не знаю, как решить эту проблему, используя python, учитывая, что загрузка всего файла в память для сортировки может вызвать ошибки памяти. У меня есть некоторые поверхностные знания о различных алгоритмах сортировки, однако все они, кажется, требуют, чтобы весь объект, который нужно отсортировать, был загружен в память.
Любые советы о том, как подойти к этому, будут высоко оценены.