Представляем FugueSQL – SQL для Pandas, Spark и Dask DataFrames
Мотивация
Как специалист по исследованию данных, вы можете быть знакомы и с Pandas. Однако вам могут понадобиться запросы и трюки преобразования данных, которые вам удобнее выполнять на SQL, а не на Python.
Вы можете использовать датафрейм pandas DataFrame следующим образом:
import pandas as pd
df = pd.DataFrame({"col1": [1, 2, 3, 4], "col2": ["a", "b", "c", "c"]})
df
…тоже самое с SQL:
Или использовать функцию Python внутри SQL-запроса?
# schema: *, col3:str
def str_concat(df: pd.DataFrame, delimeter: str) -> pd.DataFrame:
df = df.assign(col3=df["col1"].astype(str) + delimeter + df["col2"])
return df
Вот тут-то и пригодится FugueSQL.
Что такое FugueSQL?
FugueSQL – это библиотека Python, которая позволяет пользователям комбинировать код на языке Python и команды SQL. Это дает пользователям возможность гибко переключаться между Python и SQL в Jupyter Notebook или dyenhb Python-скрипта.
Чтобы установить FugueSQL, используйте команду:
pip install fugue[sql]
Для запуска на Spark или Dask введите:
pip install fugue[sql, spark]
pip install fugue[sql, dask]
pip install fugue[all]
В этой статье мы рассмотрим некоторые полезные функции FugueSQL и сравним FugueSQL с другими инструментами, такими как pandasql.
FugueSQL в блокноте
FugueSQL поставляется с расширением Jupyter notebook, которое позволяет пользователям интерактивно запрашивать DataFrames с подсветкой синтаксиса.
Чтобы использовать его, импортируйте функцию setup из fugue_notebook и напишите отдельную командлу в ячееку %%fsql. Пока этот фкнкционал доступен только для классических блокнотов (недоступно для JupyterLab).
Посмотрим на код:
Чтобы понять, как работает ячейка %%fsql, начнем с создания pandas DataFrame:
import pandas as pd
df = pd.DataFrame({"col1": [1, 2, 3, 4], "col2": ["a", "b", "c", "c"]})
df
Теперь можно сделать запрос, как это обычно делается в SQL, добавив в начало ячейки %%fsql.
В приведенном выше коде только PRINT не соответствует стандартному SQL. Это аналогично операциям pandas head() и Spark show() для отображения ряда строк.
Такие операции, как GROUP BY, аналогичны стандартному синтаксису SQL.
Усовершенствованный интерфейс SQL
Для пользователей SQL ничего необычного, за исключением оператора PRINT, не будет. Однако Fugue также вносит интерсные усовершенствования в стандартный SQL, позволяя ему изящно обрабатывать данные и делать процессы обработки данных изящнее.
Работа с временными таблицами
Пользователям SQL часто приходится использовать временные таблицы или общие табличные выражения (CTE) для хранения промежуточных данных. К счастью, FugueSQL поддерживает создание промежуточных таблиц с помощью присваивания переменной.
Например, используя df мы можем присвоить его другой переменной df2 и сохранить df2 в файл с помощью переменной SAVE OVERWRITE имя_файла .
Теперь, если мы хотим применить к df2 дополнительные преобразования, просто загрузите его из сохраненного ранее файла.
Очень круто, не правда ли?
Добавлены ключевые слова
Грамматика SQL предназначена для работы с запросами, поэтому в ней отсутствуют ключевые слова для работы с данными. В FugueSQL добавлены некоторые ключевые слова для обычных операций с DataFrame. Например:
- DROP
- FILL NULLS PARAMS
- SAMPLE
Полный список операторов приведен в документации по операторам FugueSQL.
Интеграция с Python
FugueSQL также позволяет использовать функции Python внутри SQL-запроса с помощью TRANSFORM .
Например, для использования функции str_concat в SQL-запросе:
def str_concat(df, delimeter):
df = df.assign(col3=df["col1"].astype(str) + delimeter + df["col2"])
return df
… достаточно добавить в функцию следующие компоненты:
# schema: *, col3:str
def str_concat(df: pd.DataFrame, delimeter: str) -> pd.DataFrame:
df = df.assign(col3=df["col1"].astype(str) + delimeter + df["col2"])
return df
Отлично! Теперь мы готовы добавить его в SQL-запрос:
Масштабирование на основе больших данных
FugueSQL Spark
Одним из замечательных свойств SQL является то, что он работает с любыми размерами данных. Логика обработки данных выражается без учета масштаба и остается неизменной даже при работе на Pandas, Spark или Dask.
С помощью FugueSQL мы можем применить ту же логику на движке выполнения Spark, что и на pandas просто указав %%fsql spark . Нам даже не нужно редактировать функцию str_concatfunction, чтобы перенести ее на Spark, поскольку Fugue позаботится о ее переносе.
PREPARTITION BY
Одной из важных составляющих распределенных вычислений является разбиение данных на ссабсеты.
Для этого в FugueSQL имеется ключевое слово PREPARTITION BY. Семантика предварительного разбиения-преобразования в Fugue эквивалентна семантике pandas groupby-apply .
Обратите внимание, что приведенная выше функция get_median вызывается один раз для каждого отдельного значения в столбце col2 . Поскольку данные предварительно разбиты на разделы, мы можем просто вытащить первое значение из col2, чтобы узнать, с какой группой мы работаем.
FugueSQL в производстве
Чтобы вывести FugueSQL из блокнотов Jupyter в сценарии Python, достаточно обернуть запрос FugueSQL в класс fsql. Затем мы можем вызвать метод .run() и выбрать механизм выполнения.
from fugue_sql import fsql
import fugue_spark
fsql(
"""SELECT *
FROM df
TRANSFORM PREPARTITION BY col2 USING get_median
PRINT"""
).run("spark")
В чем разница между FugueSQL и pandasql?
Если вы знакомы с pandasql, то у вас может возникнуть вопрос: Зачем использовать FugueSQL, если pandasql уже позволяет выполнять SQL с помощью pandas?
pandasql имеет единственный бэкэнд – SQLite. Передача данных между pandas и SQLite сопряжена с большими накладными расходами. С другой стороны, FugueSQL поддерживает несколько локальных бэкендов: pandas, DuckDB и SQLite.
При использовании бэкенда pandas Fugue напрямую транслирует операции SQL в операции pandas, поэтому передача данных полностью отсутствует. DuckDB имеет превосходную поддержку pandas, поэтому расходы на передачу данных также незначительны. И Pandas, и DuckDB являются предпочтительными бэкендами FugueSQL для локальной обработки данных.
Fugue также поддерживает Spark, Dask и cuDF (через blazingSQL) в качестве бэкендов.
Заключение
Поздравляем! Вы только что узнали, как использовать FugueSQL в качестве SQL-интерфейса для работы с Python DataFrames. С помощью FugueSQL вы теперь можете использовать синтаксис SQL для выражения сквозных рабочих процессов с данными и масштабирования распределенных вычислений!