Сжатие существующего большого CSV-файла с помощью Python с помощью GZIP в машине с низким объемом памяти

#python #compression #gzip

Вопрос:

Я пытаюсь взять существующий csv-файл на небольшой виртуальной машине Windows 10 объемом около 17 ГБ и сжать его с помощью gzip. Он слишком велик, чтобы его можно было прочитать в памяти.

Ищу способы сделать это эффективно, не требующие разбиения файла на разделы.

Это то, что я пытаюсь сделать прямо сейчас, и это довольно медленно:

 import gzip
import shutil

with open('file_to_be_compressed.csv', 'rb') as f_in:
    with gzip.open('test_out.csv.gz', 'wb') as f_out:
        shutil.copyfileobj(f_in, f_out)
 

Редактировать:
Это часть конвейера, в котором я загружаю данные из одного источника и загружаю их в другой. Загрузка будет намного быстрее, если я смогу сначала сжать файлы (к сожалению, они еще не были сжаты на стороне источника).
Итак, у меня есть код, который извлекает список файлов, и для каждого файла я хотел бы сжать его, а затем загрузить.

Комментарии:

1. Какая операционная система? Вы хотите сохранить исходный файл? Обычно это делается с помощью внешней утилиты. gzip thefile.csv сжал бы thefile.csv.gz и удалил оригинал.

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

3. Вы сжимаете 17 гигабайт с помощью gzip, используя максимальный уровень сжатия. Основываясь на различных критериях, вы можете ожидать скорость сжатия около 10 Мбит/с, поэтому общее время сжатия файла может составлять около получаса. Уменьшите уровень сжатия-снижение до уровня 6 приведет к незначительному ухудшению степени сжатия, и это будет в 2-3 раза быстрее.

4. Вы можете использовать подпроцесс для внешнего вызова gzip. Это будет быстрее, чем прохождение кода на python. Хотя, скорее всего, немного быстрее. Сжатие занимает время.

5. @tdelaney Я сомневаюсь, что это что-то изменит, узким местом обязательно будет GZip, а не Python или IO. Я даже протестировал его локально, разница между запуском скрипта Python и простым использованием gzip в командной строке с одинаковым уровнем сжатия составляет около 0,2 секунды.

Ответ №1:

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

Если это правильно, то вам не нужно записывать ни несжатые, ни сжатые данные в файлы. Вместо этого вы можете загружать фрагмент за раз, сжимать по ходу и загружать сжатые данные.

Для этого используйте zlib. Создайте zlib.compressobj() объект со wbits значением 31 , равным , чтобы выбрать формат gzip. Допустим, вы называете этот объект gz . Затем используйте gz.compress(data) для каждого фрагмента .csv, который вы загружаете. Загрузите результат, возвращенный каждым gz.compress(data) . Когда загрузка будет завершена, загрузите результат gz.flush() , чтобы завершить сжатые данные.