www.machinelearningmastery.ru

Машинное обучение, нейронные сети, искусственный интеллект
Header decor

Home

Оптимизированные операции ввода / вывода в Python

Дата публикации Dec 3, 2018

Работая с приложениями, интенсивно использующими данные, я часто сталкиваюсь с проблемами ввода / вывода (I / O), которые представляют собой узкое место для каждого критически важного приложения. С увеличением объема хранимых данных возникает необходимость хранить данные на дисках, чтобы компенсировать недостаток ОЗУ путем загрузки данных с диска в ОЗУ и наоборот. Операции ввода / вывода, таким образом, являются по существу очень важными задачами, когда речь идет об обработке финансовых данных или любых научных данных.

В этом посте я пытаюсь пролить свет на несколько библиотек и их хитрости в торговле. Python имеет встроенные возможности, которые можно использовать для хранения объекта на диске и считывания его с диска в оперативную память. Кроме того, Python надежен в обработке текстовых файлов и баз данных SQL. Библиотека Pandas предоставляет множество классов и методов для чтения и записи файлов в широком диапазоне форматов.

Мы собираемся изучить следующие области хранения данных и методы поиска здесь:

  1. Сериализованное хранилище с использованием модуля Pickle
  2. Операции ввода / вывода с текстовыми данными
  3. Базы данных SQL
  4. I / O с PyTables

2 основных фактора, которые учитываются при оптимизации операций ввода-вывода в языке Python, - это эффективность (производительность) и гибкость. Давайте погрузимся прямо в это:

Сериализованное хранилище с использованием модуля Pickle

Существует множество модулей на языке Python, которые можно легко использовать в крупномасштабных установках.

Использование модуля pickle для чтения и записи файлов

Вам необходимо сохранить данные на вашем диске, чтобы поделиться, документировать или использовать их позже. У нас есть модуль pickle, который сериализует объект python, чтобы быстро выполнять операции чтения и записи.

# On running the above code snippet, you'll see:CPU times: user 40.9 ms, sys: 14 ms, total: 54.9 ms
Wall time: 54.5 ms

Случайные числа с плавающей точкой создают файл размером 9 МБ, который сериализуется в поток байтов и записывается на диск за 54,9 мс. Вы будете использоватьсвалкаа такженагрузкафункция модуля pickle для записи и чтения файла соответственно. Чтобы утверждать сериализованные и десериализованные данные, вы можете использовать Numpy'sallcloseметод. Вот как вы можете это сделать:

np.allclose(np.array(a1), np.array(a2))# here a2 is the deserialized object after reading the same file
# using the load function.

Таким образом, модуль pickle сохраняет список Python, dict и т. Д. После преобразования их в поток символов на диске. Суть в том, что этот поток байтов содержит информацию, необходимую для восстановления объекта в другом скрипте Python.

Операции ввода / вывода с текстовыми данными

Python был популярным языком, особенно когда имеешь дело с текстовыми файлами из-за надежности и простоты обработки текстовых данных. Существует несколько опций для работы со строковыми объектами и с текстовыми файлами в целом.

Чтобы написать CSV (значения, разделенные запятыми), мы можем использовать методы write и readline:

csv_file.write(header)# time is time array and data is the dummy numpy array
for time, (a, b, c, d, e) in zip(time, data):
s = '%s,%f,%f,%f,%f,%f\n' % (time, a, b, c, d, e) csv_file.write(s)csv_file.close()# to read the file, we can use readlines function
content = csv_file.readlines()

Хотя python предоставляет методы для обработки текстовых файлов, у нас есть библиотека pandas, которая может читать и записывать различные форматы данных, и это намного лучше и проще.

Будь то CSV (значение, разделенное запятыми), SQL (язык структурированных запросов), XLS / XLSX (файлы Microsoft Excel), JSON (нотация объектов Javascript) или HTML (язык разметки гипертекста).

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

%time data.to_csv(filename + '.csv')# CPU times: user 5.59 s, sys: 137 ms, total: 5.69 s# And to read the files back from the diskpd.read_csv(<path to the CSV file>)

Базы данных SQL

Python поставляется с поддержкой базы данных SQL, которая является SQLite3. Мы можем работать практически с любой базой данных (SQL или NoSQL) с python.

SQL-запросы записываются как строковые объекты, где синтаксис и типы данных зависят от используемой базы данных. Иллюстрирование создания таблицы Todo через python в базе данных SQLite:

import sqlite3 as sq# query string to create the tablequery = 'CREATE TABLE TODO_NUMBER (Num1 real, Num2 real, Num3 real)'
con = sq.connect(path + 'todo.db')
con.execute(query)
con.commit()

Давайте попробуем вставить некоторые данные в созданную базу данных,

data = np.random.standard_normal((1000000, 3))
%%time
con.executemany('INSERT INTO TODO_NUMBER VALUES (?, ?, ?, ?, ?)', data)
con.commit()# Time taken: CPU times: user 10.3 s, sys: 316 ms, total: 10.6 s
Wall time: 11 s

Запись 1 миллиона строк в базу данных - это немного тяжелая и трудоемкая задача. Чтение базы данных намного быстрее:

con.execute('SELECT * FROM TODO_NUMBER').fetchall() 

Если вы имеете дело с большим количеством чисел и массивов в вашей базе данных, вы можете использовать массивы Numpy для чтения данных непосредственно в Numpy ndarray.

np_query = 'SELECT * FROM TODO_NUMBER WHERE Num1 > 0 AND Num2 < 0'
res = np.array(con.execute(np_query).fetchall()).round(3)

Это очень хороший хак, чтобы читать и выводить на экран результаты запроса без суеты. Чтобы сделать чтение более эффективным и оптимизированным, мы должны читать целые таблицы и запрашивать результаты с помощью панд. Аналитика и обработка становятся намного быстрее, когда вся таблица загружается в память. Это достигается с помощью библиотекиpandas.io.sql

import pandas.io.sql as pds
data_df = pds.read_sql('SELECT * FROM TODO_NUMBERS', con)

Теперь таблица загружается в память, что позволяет значительно ускорить обработку. SQL-запрос, который занимает несколько секунд с SQLite3, завершается за миллисекунды с пандами в памяти:

%time data_df[(data_df['Num1'] > 0) & (data_df['Num2'] < 0)].head()# CPU times: user 50 ms, sys: 0 ns, total: 50 ms# Wall time: 49.9 ms

Мы можем выполнять более сложные запросы с пандами, которые дадут результат намного быстрее, чем SQL, но он не может заменить SQL. Учитывая, что pandas может реплицировать SQL-запрос, мы можем значительно ускорить аналитику, используя обработку pandas в памяти.

Здесь следует отметить, что pandas не был создан для замены базы данных SQL, и при этом он не может делать то же самое в данный момент. Pandas не поддерживает реляционные структуры данных.

I / O с PyTables

PyTables - это привязка Python для стандарта базы данных / файла HDF5 Он специально спроектирован и разработан для повышения производительности операций ввода-вывода и максимально эффективного использования доступного оборудования. Он очень хорошо работает для ускорения аналитики и ускорения генерации результатов. База данных PyTables может вместить множество таблиц и поддерживает сжатие и индексацию, а также нетривиальные запросы к таблицам.

PyTables имеет файловый формат базы данных. Давайте пройдемся по работе за столами,

Это создаст для нас таблицу с обязательными полями с указанными dtypes. Теперь давайте заполним базу данных, нам нужно будет создать несколько случайных значений и записать их построчно в таблицу следующим образом:

Но опять же, у нас есть еще один оптимизированный и Pythonic способ достичь того же результата, используя структурированные массивы NumPy:

dty = np.dtype([('Num1', 'i4'), ('Num2', '<i4')])sarray = np.zeros(len(ran_int), dtype=dty)

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

%%time
h5.create_table('/', 'ints_from_array', sarray,title='Integers', expectedrows=rows, filters=filters)

Этот подход быстрее, и мы достигаем тех же результатов с меньшим количеством строк кода. Мы можем удалить дубликат таблицы, используя это:

h5.remove_node(‘/’, ‘ints_from_array’)

И pandas, и PyTables имеют возможность обрабатывать сложные SQL-подобные запросы, а также индексирование и выборки. Они оба спроектированы и оптимизированы по скорости, когда дело доходит до операций ввода-вывода.

Основным преимуществом использования PyTables является его modus operandi для сжатия. Он использует сжатие не только для экономии места на диске, но и для повышения производительности операций ввода-вывода.

Выводы

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

Реляционные базы данных имеют свои плюсы, если у вас есть сложные структуры данных, которые демонстрируют ряд связей между отдельными объектами / таблицами. Это может оказаться оправданным в определенных обстоятельствах, когда существует недостаток производительности по сравнению с чистыми подходами на основе NumPy ndarray или pandas на основе DataFrame.

Оригинальная статья

Footer decor

© www.machinelearningmastery.ru | Ссылки на оригиналы и авторов сохранены. | map