(Pandas + SQL) Обзор Python-библиотеки PandaSQL

Pandas уже давно является неотъемлемым инструментом в арсенале любого специалиста, работающего с данными на языке Python. Ровно также неотъемлемым навыком является знание языка SQL, предназначенного для извлечения, хранения и модификации данных из реляционных баз.

В данной статье будет рассмотрена еще одна python-библиотека PandaSQL, которая позволяет использовать язык запросов SQL для обработки табличных данных pandas (DataFrame).

Данная библиотека может быть полезна:

  • специалистам, знающим SQL, но еще не знакомых с синтаксисом pandas, при этом уже готовый код будет для них более читабельным;
  • в случаях, когда задачу выгрузки данных интуитивно легче сформулировать средствами декларативного языка запросов SQL.

Установить данную библиотеку можно следующими командами:

  • для Pip: pip install pandasql;
  • для Anaconda: conda install pandasql.

В целях демонстрации функционала данного модуля мы используем Mall Customers Dataset – открытые данные посетителей магазина (id, пол, возраст, доход, рейтинг трат) с сайта Kaggle.

Важное напоминание: c помощью PandaSQL можно обращаться только к данным в виде pandas dataframe, поэтому наряду с ним необходимо импортировать сам pandas.

(Pandas + SQL) Обзор Python-библиотеки PandaSQL

Давайте выберем из исходной таблицы покупателей, чей возраст не превышает 25 лет и годовой доход составляет не менее 60 тыс. долларов.

В Pandas это можно реализовать следующим образом:

(Pandas + SQL) Обзор Python-библиотеки PandaSQL

При помощи модуля PandaSQL:

Присвоим некоторой переменной sql_query запрос на языке SQLite, заключенный в тройные кавычки, а затем передадим эту переменную в функцию sqldf.

(Pandas + SQL) Обзор Python-библиотеки PandaSQL

На выходе мы получаем такой же результат, как и в примере с использованием Pandas.

Помимо непосредственно sql-запроса, функция sqldf принимает также необязательные аргументы в виде словарей locals() и globals(), означающих пространство имен, используемых в запросе.

При работе с модулем PandaSQL важно помнить, что он имеет некоторые ограничения и, как упоминалось выше, реализует язык запросов СУБД SQLite, который в свою очередь также имеет ряд ограничений по сравнению с более известными MySQL, PostreSQL, MS SQL Server.

В этой связи важное уточнение:

  • PandaSQL реализует только запросы. Создание, модификация, удаление таблиц невозможны.
  • Нельзя применить операции RIGHT OUTER JOIN и FULL OUTER JOIN. Однако LEFT OUTER JOIN применяется.

Оконные функции. Группировка. Фильтрация.

Давайте вычислим средний доход и средний возраст среди 7 мужчин и 7 женщин с наиболее высоким уровнем трат (показатель Spending Score). Для этого нам понадобятся оконная функция и группировка с агрегированием.

(Pandas + SQL) Обзор Python-библиотеки PandaSQL

Средствами самого Pandas необходимые нам данные можно получить следующим образом:

(Pandas + SQL) Обзор Python-библиотеки PandaSQL

Как видим, нам пришлось для каждого пола создавать отдельный dataframe и соединять их через функцию concat(). Но будь у нас не 2 группы, как сейчас, а больше, это могло бы вызвать некоторые трудности в реализации. В то же время, запрос через PandaSQL работал бы так же, будь у нас и большее количество полей для группировки.

Это один из многочисленных примеров, когда язык SQL позволяет легче реализовать задачу выгрузки и отбора данных.

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

1717
9 комментариев

Спасибо за статью. Весьма кстати

1
Автор

Спасибо за позитивную обратную связь, всегда рады помочь!

Дак в pandas есть read_sql, куда тоже можно засунуть этот запрос query и передать коннекшн. А так сравниваете чтение csv и последующую обработку и из sql таблицы. Вообще не понятно такое сравнение и польза от данной библиотеки

Мало ты работал с pandas.
Статья очень полезная

1

Я так понял, что тут ты можешь писать sql запросы к датафреймам, а read_sql из базы

В pandas можно сделать проще.
Реализация рассчитана на любое количество групп.

df = df.sort_values(['Genre', 'Spending Score (1-100)'])
b = [df[df.Genre == i].iloc[-7:, [2,3]].mean().values for i in df.Genre.unique()]
pd.DataFrame(b, index = pd.Index(df.Genre.unique(), name='Пол'), columns=['Средний возраст', 'Средний годовой доход'])