Храните любой объект 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.
- Обработка или сжатие определенных объектов класса может не работать. В этих случаях попробуйте сохранить атрибуты класса (обычно доступные в виде словаря), а затем загрузить другой экземпляр класса и назначить ему атрибуты.
Вот и все. В будущем я буду писать больше статей о простых, но замечательно полезных функциях и классах, которые я часто использую в своих проектах. Некоторые из них основаны на том, что мы здесь видели, другие - нет.
Спасибо за прочтение.