Храните любой объект Python быстрее и с меньшим размером файла

Вы ненавидите, как долго загружаются данные? На вашем жестком диске мало свободного места? Вот четыре простые в реализации функции, которые помогут любому программисту Python, от новичка до продвинутого, управлять своими проектами.

Сжатые соленья

Если вы какое-то время работали с Python, возможно, вы знакомы с библиотекой _pickle.

Он сохраняет почти любой объект Python (включая массивные наборы данных) как байты. Это сокращает время загрузки до доли. В зависимости от объекта это также может сэкономить вам место. Однако часто этого бывает недостаточно.

Войдите в библиотеку bz2 для python, которая включает сжатие bz2 для любого файла. Пожертвовав некоторой скоростью, полученной при сборке данных, вы можете сжать их до четверти исходного размера.

Четыре функции

Ниже приведены четыре метода Python, которые быстро справляются с работой с данными, функции, которые я включаю в utils.py файл любого проекта, над которым я работаю.

Импорт

import bz2
import pickle
import _pickle as cPickle

1. Полный рассол

Метод full_pickle принимает практически любой объект (list, dictionary, pandas.DataFrame и другие) и сохраняет его как .pickle файл.

# Saves the "data" with the "title" and adds the .pickle
def full_pickle(title, data):
 pikd = open(title + ‘.pickle’, ‘wb’)
 pickle.dump(data, pikd)
 pikd.close()

Пример использования:

full_pickle('filename', data) 
  • filename - это имя файла без расширения.
  • data - это любой объект.

2. Ослабьте

Загрузите файлы рассола, которые вы или другие сохранили, используя метод loosen . Включите расширение .pickle в file аргумент.

# loads and returns a pickled objects
def loosen(file):
 pikd = open(file, ‘rb’)
 data = pickle.load(pikd)
 pikd.close()
 return data

Пример использования:

data = loosen('example_pickle.pickle') 
  • file - это имя файла с расширением .pickle.

3. Сжатый рассол

compressed_pickle работает так же, как full_pickle. Здесь даже нужны те же аргументы. Он создает объект pickle, а затем сжимает его с помощью библиотеки bz2, автоматически добавляя расширение .pbz2 к сохраненному файлу.

# Pickle a file and then compress it into a file with extension 
def compressed_pickle(title, data):
 with bz2.BZ2File(title + ‘.pbz2’, ‘w’) as f: 
 cPickle.dump(data, f)

Пример использования:

compressed_pickle('filename', data) 
  • filename - это имя файла без расширения.
  • data - это любой объект.

Обратите внимание, что это сжимает файл pickle, наоборот, он не работает.

4. Распаковать рассол.

Метод decompress_pickle работает так же, как функция loosen. Включите расширение .pbz2 в file аргумент.

# Load any compressed pickle file
def decompress_pickle(file):
 data = bz2.BZ2File(file, ‘rb’)
 data = cPickle.load(data)
 return data

Пример использования:

data = decompress_pickle('example_cp.pbz2') 
  • file - это имя файла с расширением .pbz2.

Контрольные точки

Итак, насколько быстрее происходит травление и сколько места мы экономим?

Вот эталонный тест, который я выполнил на виртуальной машине AWS менее чем за пенни (0,01 доллара) с использованием модуля, который я создал для облачных вычислений.

Save CSV File: 3.384 seconds
Load CSV File: 1.977 seconds
CSV File Size: 39,575,154 bytes
Save Pickle File: 3.422 seconds
Load Pickle File: 0.156 seconds
Pickle File Size: 40,759,166 bytes
Save Compressed Pickle: 4.837
Load Compressed Pickle: 1.139
Compressed Pickle File Size: 1,467,842

Сохранение объекта pandas.DataFrame() размером 39 МБ в виде файла .csv заняло 3,4 секунды. Почти столько же, сколько потребовалось для сохранения .pickle файла, и более чем на одну секунду быстрее, чем на сжатие.

Файл .pickle и файлы .csv занимали примерно одинаковое пространство, около 40 МБ, но сжатый файл pickle занимал всего 1,5 МБ. Это много сэкономленного места.

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

Загрузка .csv файла заняла 2 секунды, загрузка сжатого файла pickle .pbz2 заняла всего 1,2 секунды, тогда как загрузка файлов pickle заняла всего 0,15 секунды.

Вещи, на которые стоит обратить внимание

  • Порядок травления и сжатия проверяется и работает без ухудшения данных. Изменение порядка приводит к ухудшению производительности.
  • Возможно, вы захотите попробовать другие методы сжатия, которые лучше подходят для ваших нужд, чем сжатие bz2.
  • Обработка или сжатие определенных объектов класса может не работать. В этих случаях попробуйте сохранить атрибуты класса (обычно доступные в виде словаря), а затем загрузить другой экземпляр класса и назначить ему атрибуты.

Вот и все. В будущем я буду писать больше статей о простых, но замечательно полезных функциях и классах, которые я часто использую в своих проектах. Некоторые из них основаны на том, что мы здесь видели, другие - нет.

Спасибо за прочтение.