Интеграция с Ibis
Ibis — это библиотека Python для работы с фреймворками данных, поддерживающая более 20 бэкэндов, по умолчанию используется DuckDB. Ibis с DuckDB предоставляет удобный питонический интерфейс для SQL с высокой производительностью.
Установка
Вы можете установить Ibis с бэкэндом DuckDB:
pip install 'ibis-framework[duckdb,examples]' # examples is only required to access the sample data Ibis provides
или использовать conda:
conda install ibis-framework
или использовать mamba:
mamba install ibis-framework
Создание файла базы данных
Ibis может работать с несколькими типами файлов, но по своей сути он подключается к существующим базам данных и взаимодействует с данными в них. Вы можете начать работу со своими базами данных DuckDB или создать новую с образцовыми данными.
import ibis
con = ibis.connect("duckdb://penguins.ddb")
con.create_table(
"penguins", ibis.examples.penguins.fetch().to_pyarrow(), overwrite = True
) # Output: DatabaseTable: penguins species string island string bill_length_mm float64 bill_depth_mm float64 flipper_length_mm int64 body_mass_g int64 sex string year int64
Теперь вы можете увидеть, как примерный набор данных скопирован в базу данных:
# reconnect to the persisted database (dropping temp tables)
con = ibis.connect("duckdb://penguins.ddb")
con.list_tables() # Output: ['penguins']
Существует одна таблица, называемая penguins. Мы можем попросить Ibis предоставить нам объект, с которым можно взаимодействовать.
penguins = con.table("penguins")
penguins # Output: DatabaseTable: penguins species string island string bill_length_mm float64 bill_depth_mm float64 flipper_length_mm int64 body_mass_g int64 sex string year int64
Ibis лениво вычисляет результаты, поэтому вместо данных мы видим схему таблицы. Чтобы посмотреть данные, мы можем вызвать head и затем to_pandas, чтобы получить несколько первых строк таблицы в виде pandas DataFrame.
penguins.head().to_pandas()
species island bill_length_mm bill_depth_mm flipper_length_mm body_mass_g sex year 0 Adelie Torgersen 39.1 18.7 181.0 3750.0 male 2007 1 Adelie Torgersen 39.5 17.4 186.0 3800.0 female 2007 2 Adelie Torgersen 40.3 18.0 195.0 3250.0 female 2007 3 Adelie Torgersen NaN NaN NaN NaN None 2007 4 Adelie Torgersen 36.7 19.3 193.0 3450.0 female 2007
to_pandas принимает существующее ленивое выражение таблицы и вычисляет его. Если мы его упустим, вы увидите представление Ibis выражения таблицы, которое to_pandas вычислит (когда вы будете готовы!).
penguins.head()
# Output: r0 := DatabaseTable: penguins species string island string bill_length_mm float64 bill_depth_mm float64 flipper_length_mm int64 body_mass_g int64 sex string year int64 Limit[r0, n=5]
Ibis возвращает результаты в виде pandas DataFrame, используя to_pandas, но не использует pandas для выполнения вычислений. Запрос выполняется DuckDB. Только при вызове to_pandas Ibis получает результаты и преобразует их в DataFrame.
Интерактивный режим
В остальной части этого введения мы включим интерактивный режим, который частично выполняет запросы, чтобы предоставить пользователям предварительный просмотр результатов. Существует небольшая разница в формате вывода, но в остальном это то же самое, что и вызов to_pandas на выражении таблицы с ограничением на 10 строк возвращаемых результатов.
ibis.options.interactive = True penguins.head()
┏━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━┓ ┃ species ┃ island ┃ bill_length_mm ┃ bill_depth_mm ┃ flipper_length_mm ┃ body_mass_g ┃ sex ┃ year ┃ ┡━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━┩ │ string │ string │ float64 │ float64 │ int64 │ int64 │ string │ int64 │ ├─────────┼───────────┼────────────────┼───────────────┼───────────────────┼─────────────┼────────┼───────┤ │ Adelie │ Torgersen │ 39.1 │ 18.7 │ 181 │ 3750 │ male │ 2007 │ │ Adelie │ Torgersen │ 39.5 │ 17.4 │ 186 │ 3800 │ female │ 2007 │ │ Adelie │ Torgersen │ 40.3 │ 18.0 │ 195 │ 3250 │ female │ 2007 │ │ Adelie │ Torgersen │ nan │ nan │ NULL │ NULL │ NULL │ 2007 │ │ Adelie │ Torgersen │ 36.7 │ 19.3 │ 193 │ 3450 │ female │ 2007 │ └─────────┴───────────┴────────────────┴───────────────┴───────────────────┴─────────────┴────────┴───────┘
Основные операции
Ibis имеет набор полезных методов таблиц для манипулирования и запроса данных в таблице.
фильтр
filter позволяет вам выбирать строки на основе условия или набора условий.
Мы можем отфильтровать, чтобы у нас были только пингвины вида Adelie:
penguins.filter(penguins.species == "Gentoo")
┏━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━┓ ┃ species ┃ island ┃ bill_length_mm ┃ bill_depth_mm ┃ flipper_length_mm ┃ body_mass_g ┃ sex ┃ year ┃ ┡━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━┩ │ string │ string │ float64 │ float64 │ int64 │ int64 │ string │ int64 │ ├─────────┼────────┼────────────────┼───────────────┼───────────────────┼─────────────┼────────┼───────┤ │ Gentoo │ Biscoe │ 46.1 │ 13.2 │ 211 │ 4500 │ female │ 2007 │ │ Gentoo │ Biscoe │ 50.0 │ 16.3 │ 230 │ 5700 │ male │ 2007 │ │ Gentoo │ Biscoe │ 48.7 │ 14.1 │ 210 │ 4450 │ female │ 2007 │ │ Gentoo │ Biscoe │ 50.0 │ 15.2 │ 218 │ 5700 │ male │ 2007 │ │ Gentoo │ Biscoe │ 47.6 │ 14.5 │ 215 │ 5400 │ male │ 2007 │ │ Gentoo │ Biscoe │ 46.5 │ 13.5 │ 210 │ 4550 │ female │ 2007 │ │ Gentoo │ Biscoe │ 45.4 │ 14.6 │ 211 │ 4800 │ female │ 2007 │ │ Gentoo │ Biscoe │ 46.7 │ 15.3 │ 219 │ 5200 │ male │ 2007 │ │ Gentoo │ Biscoe │ 43.3 │ 13.4 │ 209 │ 4400 │ female │ 2007 │ │ Gentoo │ Biscoe │ 46.8 │ 15.4 │ 215 │ 5150 │ male │ 2007 │ │ … │ … │ … │ … │ … │ … │ … │ … │ └─────────┴────────┴────────────────┴───────────────┴───────────────────┴─────────────┴────────┴───────┘
Или отфильтровать пингвинов вида Gentoo, у которых масса тела больше 6 кг.
penguins.filter((penguins.species == "Gentoo") & (penguins.body_mass_g > 6000))
┏━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━┓ ┃ species ┃ island ┃ bill_length_mm ┃ bill_depth_mm ┃ flipper_length_mm ┃ body_mass_g ┃ sex ┃ year ┃ ┡━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━┩ │ string │ string │ float64 │ float64 │ int64 │ int64 │ string │ int64 │ ├─────────┼────────┼────────────────┼───────────────┼───────────────────┼─────────────┼────────┼───────┤ │ Gentoo │ Biscoe │ 49.2 │ 15.2 │ 221 │ 6300 │ male │ 2007 │ │ Gentoo │ Biscoe │ 59.6 │ 17.0 │ 230 │ 6050 │ male │ 2007 │ └─────────┴────────┴────────────────┴───────────────┴───────────────────┴─────────────┴────────┴───────┘
Вы можете использовать любое булево сравнение в фильтре (хотя, если вы попытаетесь сделать что-то вроде < над строкой, Ibis вас об этом оповестит).
выбрать
Ваш анализ данных может не требовать всех столбцов, присутствующих в данной таблице. select позволяет выбрать только те столбцы, с которыми вы хотите работать.
Чтобы выбрать столбец, вы можете использовать имя столбца как строку:
penguins.select("species", "island", "year").limit(3) ┏━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━┓ ┃ species ┃ island ┃ year ┃ ┡━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━┩ │ string │ string │ int64 │ ├─────────┼───────────┼───────┤ │ Adelie │ Torgersen │ 2007 │ │ Adelie │ Torgersen │ 2007 │ │ Adelie │ Torgersen │ 2007 │ │ … │ … │ … │ └─────────┴───────────┴───────┘
Или вы можете использовать объекты столбцов напрямую (это может быть удобно в сочетании с автодополнением):
penguins.select(penguins.species, penguins.island, penguins.year).limit(3)
┏━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━┓ ┃ species ┃ island ┃ year ┃ ┡━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━┩ │ string │ string │ int64 │ ├─────────┼───────────┼───────┤ │ Adelie │ Torgersen │ 2007 │ │ Adelie │ Torgersen │ 2007 │ │ Adelie │ Torgersen │ 2007 │ │ … │ … │ … │ └─────────┴───────────┴───────┘
Или вы можете смешивать и сочетать:
penguins.select("species", "island", penguins.year).limit(3) ┏━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━┓ ┃ species ┃ island ┃ year ┃ ┡━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━┩ │ string │ string │ int64 │ ├─────────┼───────────┼───────┤ │ Adelie │ Torgersen │ 2007 │ │ Adelie │ Torgersen │ 2007 │ │ Adelie │ Torgersen │ 2007 │ │ … │ … │ … │ └─────────┴───────────┴───────┘
изменить
mutate позволяет добавлять новые столбцы в вашу таблицу, полученные из значений существующих столбцов.
penguins.mutate(bill_length_cm=penguins.bill_length_mm / 10)
┏━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━━━┓ ┃ species ┃ island ┃ bill_length_mm ┃ bill_depth_mm ┃ flipper_length_mm ┃ body_mass_g ┃ sex ┃ year ┃ bill_length_cm ┃ ┡━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━━━┩ │ string │ string │ float64 │ float64 │ int64 │ int64 │ string │ int64 │ float64 │ ├─────────┼───────────┼────────────────┼───────────────┼───────────────────┼─────────────┼────────┼───────┼────────────────┤ │ Adelie │ Torgersen │ 39.1 │ 18.7 │ 181 │ 3750 │ male │ 2007 │ 3.91 │ │ Adelie │ Torgersen │ 39.5 │ 17.4 │ 186 │ 3800 │ female │ 2007 │ 3.95 │ │ Adelie │ Torgersen │ 40.3 │ 18.0 │ 195 │ 3250 │ female │ 2007 │ 4.03 │ │ Adelie │ Torgersen │ nan │ nan │ NULL │ NULL │ NULL │ 2007 │ nan │ │ Adelie │ Torgersen │ 36.7 │ 19.3 │ 193 │ 3450 │ female │ 2007 │ 3.67 │ │ Adelie │ Torgersen │ 39.3 │ 20.6 │ 190 │ 3650 │ male │ 2007 │ 3.93 │ │ Adelie │ Torgersen │ 38.9 │ 17.8 │ 181 │ 3625 │ female │ 2007 │ 3.89 │ │ Adelie │ Torgersen │ 39.2 │ 19.6 │ 195 │ 4675 │ male │ 2007 │ 3.92 │ │ Adelie │ Torgersen │ 34.1 │ 18.1 │ 193 │ 3475 │ NULL │ 2007 │ 3.41 │ │ Adelie │ Torgersen │ 42.0 │ 20.2 │ 190 │ 4250 │ NULL │ 2007 │ 4.20 │ │ … │ … │ … │ … │ … │ … │ … │ … │ … │ └─────────┴───────────┴────────────────┴───────────────┴───────────────────┴─────────────┴────────┴───────┴────────────────┘
Обратите внимание, что таблица немного слишком широкая, чтобы отобразить все столбцы (в зависимости от размера вашего экрана). bill_length теперь присутствует в миллиметрах и сантиметрах. Используйте select, чтобы уменьшить количество отображаемых столбцов.
penguins.mutate(bill_length_cm=penguins.bill_length_mm / 10).select(
"species",
"island",
"bill_depth_mm",
"flipper_length_mm",
"body_mass_g",
"sex",
"year",
"bill_length_cm",
) ┏━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━━━┓ ┃ species ┃ island ┃ bill_depth_mm ┃ flipper_length_mm ┃ body_mass_g ┃ sex ┃ year ┃ bill_length_cm ┃ ┡━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━━━┩ │ string │ string │ float64 │ int64 │ int64 │ string │ int64 │ float64 │ ├─────────┼───────────┼───────────────┼───────────────────┼─────────────┼────────┼───────┼────────────────┤ │ Adelie │ Torgersen │ 18.7 │ 181 │ 3750 │ male │ 2007 │ 3.91 │ │ Adelie │ Torgersen │ 17.4 │ 186 │ 3800 │ female │ 2007 │ 3.95 │ │ Adelie │ Torgersen │ 18.0 │ 195 │ 3250 │ female │ 2007 │ 4.03 │ │ Adelie │ Torgersen │ nan │ NULL │ NULL │ NULL │ 2007 │ nan │ │ Adelie │ Torgersen │ 19.3 │ 193 │ 3450 │ female │ 2007 │ 3.67 │ │ Adelie │ Torgersen │ 20.6 │ 190 │ 3650 │ male │ 2007 │ 3.93 │ │ Adelie │ Torgersen │ 17.8 │ 181 │ 3625 │ female │ 2007 │ 3.89 │ │ Adelie │ Torgersen │ 19.6 │ 195 │ 4675 │ male │ 2007 │ 3.92 │ │ Adelie │ Torgersen │ 18.1 │ 193 │ 3475 │ NULL │ 2007 │ 3.41 │ │ Adelie │ Torgersen │ 20.2 │ 190 │ 4250 │ NULL │ 2007 │ 4.20 │ │ … │ … │ … │ … │ … │ … │ … │ … │ └─────────┴───────────┴───────────────┴───────────────────┴─────────────┴────────┴───────┴────────────────┘
селекторы
Ввод всех имён столбцов кроме одного немного утомительно. Вместо этого мы можем использовать selector для быстрого выбора или отмены выбора групп столбцов.
import ibis.selectors as s
penguins.mutate(bill_length_cm=penguins.bill_length_mm / 10).select(
~s.matches("bill_length_mm")
# match every column except `bill_length_mm`
) ┏━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━━━┓ ┃ species ┃ island ┃ bill_depth_mm ┃ flipper_length_mm ┃ body_mass_g ┃ sex ┃ year ┃ bill_length_cm ┃ ┡━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━━━┩ │ string │ string │ float64 │ int64 │ int64 │ string │ int64 │ float64 │ ├─────────┼───────────┼───────────────┼───────────────────┼─────────────┼────────┼───────┼────────────────┤ │ Adelie │ Torgersen │ 18.7 │ 181 │ 3750 │ male │ 2007 │ 3.91 │ │ Adelie │ Torgersen │ 17.4 │ 186 │ 3800 │ female │ 2007 │ 3.95 │ │ Adelie │ Torgersen │ 18.0 │ 195 │ 3250 │ female │ 2007 │ 4.03 │ │ Adelie │ Torgersen │ nan │ NULL │ NULL │ NULL │ 2007 │ nan │ │ Adelie │ Torgersen │ 19.3 │ 193 │ 3450 │ female │ 2007 │ 3.67 │ │ Adelie │ Torgersen │ 20.6 │ 190 │ 3650 │ male │ 2007 │ 3.93 │ │ Adelie │ Torgersen │ 17.8 │ 181 │ 3625 │ female │ 2007 │ 3.89 │ │ Adelie │ Torgersen │ 19.6 │ 195 │ 4675 │ male │ 2007 │ 3.92 │ │ Adelie │ Torgersen │ 18.1 │ 193 │ 3475 │ NULL │ 2007 │ 3.41 │ │ Adelie │ Torgersen │ 20.2 │ 190 │ 4250 │ NULL │ 2007 │ 4.20 │ │ … │ … │ … │ … │ … │ … │ … │ … │ └─────────┴───────────┴───────────────┴───────────────────┴─────────────┴────────┴───────┴────────────────┘
Вы также можете использовать selector вместе с именем столбца.
penguins.select("island", s.numeric()) ┏━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━┓ ┃ island ┃ bill_length_mm ┃ bill_depth_mm ┃ flipper_length_mm ┃ body_mass_g ┃ year ┃ ┡━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━┩ │ string │ float64 │ float64 │ int64 │ int64 │ int64 │ ├───────────┼────────────────┼───────────────┼───────────────────┼─────────────┼───────┤ │ Torgersen │ 39.1 │ 18.7 │ 181 │ 3750 │ 2007 │ │ Torgersen │ 39.5 │ 17.4 │ 186 │ 3800 │ 2007 │ │ Torgersen │ 40.3 │ 18.0 │ 195 │ 3250 │ 2007 │ │ Torgersen │ nan │ nan │ NULL │ NULL │ 2007 │ │ Torgersen │ 36.7 │ 19.3 │ 193 │ 3450 │ 2007 │ │ Torgersen │ 39.3 │ 20.6 │ 190 │ 3650 │ 2007 │ │ Torgersen │ 38.9 │ 17.8 │ 181 │ 3625 │ 2007 │ │ Torgersen │ 39.2 │ 19.6 │ 195 │ 4675 │ 2007 │ │ Torgersen │ 34.1 │ 18.1 │ 193 │ 3475 │ 2007 │ │ Torgersen │ 42.0 │ 20.2 │ 190 │ 4250 │ 2007 │ │ … │ … │ … │ … │ … │ … │ └───────────┴────────────────┴───────────────┴───────────────────┴─────────────┴───────┘
Вы можете узнать больше о selectors в документации!
order_by
order_by упорядочивает значения одного или нескольких столбцов по возрастанию или убыванию.
По умолчанию ibis сортирует по возрастанию:
penguins.order_by(penguins.flipper_length_mm).select(
"species", "island", "flipper_length_mm"
) ┏━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓ ┃ species ┃ island ┃ flipper_length_mm ┃ ┡━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩ │ string │ string │ int64 │ ├───────────┼───────────┼───────────────────┤ │ Adelie │ Biscoe │ 172 │ │ Adelie │ Biscoe │ 174 │ │ Adelie │ Torgersen │ 176 │ │ Adelie │ Dream │ 178 │ │ Adelie │ Dream │ 178 │ │ Adelie │ Dream │ 178 │ │ Chinstrap │ Dream │ 178 │ │ Adelie │ Dream │ 179 │ │ Adelie │ Torgersen │ 180 │ │ Adelie │ Biscoe │ 180 │ │ … │ … │ … │ └───────────┴───────────┴───────────────────┘
Вы можете сортировать по убыванию, используя метод desc столбца:
penguins.order_by(penguins.flipper_length_mm.desc()).select(
"species", "island", "flipper_length_mm"
) ┏━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓ ┃ species ┃ island ┃ flipper_length_mm ┃ ┡━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩ │ string │ string │ int64 │ ├─────────┼────────┼───────────────────┤ │ Gentoo │ Biscoe │ 231 │ │ Gentoo │ Biscoe │ 230 │ │ Gentoo │ Biscoe │ 230 │ │ Gentoo │ Biscoe │ 230 │ │ Gentoo │ Biscoe │ 230 │ │ Gentoo │ Biscoe │ 230 │ │ Gentoo │ Biscoe │ 230 │ │ Gentoo │ Biscoe │ 230 │ │ Gentoo │ Biscoe │ 229 │ │ Gentoo │ Biscoe │ 229 │ │ … │ … │ … │ └─────────┴────────┴───────────────────┘
Или вы можете использовать ibis.desc
penguins.order_by(ibis.desc("flipper_length_mm")).select(
"species", "island", "flipper_length_mm"
) ┏━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓ ┃ species ┃ island ┃ flipper_length_mm ┃ ┡━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩ │ string │ string │ int64 │ ├─────────┼────────┼───────────────────┤ │ Gentoo │ Biscoe │ 231 │ │ Gentoo │ Biscoe │ 230 │ │ Gentoo │ Biscoe │ 230 │ │ Gentoo │ Biscoe │ 230 │ │ Gentoo │ Biscoe │ 230 │ │ Gentoo │ Biscoe │ 230 │ │ Gentoo │ Biscoe │ 230 │ │ Gentoo │ Biscoe │ 230 │ │ Gentoo │ Biscoe │ 229 │ │ Gentoo │ Biscoe │ 229 │ │ … │ … │ … │ └─────────┴────────┴───────────────────┘
агрегировать
Ibis предоставляет несколько агрегатных функций для обобщения данных.
mean, max, min, count, sum (и так далее).
Чтобы агрегировать весь столбец, вызовите соответствующий метод этого столбца.
penguins.flipper_length_mm.mean()
# Output: 200.91520467836258
Вы можете вычислить несколько агрегатов одновременно, используя метод aggregate:
penguins.aggregate([penguins.flipper_length_mm.mean(), penguins.bill_depth_mm.max()])
┏━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┓ ┃ Mean(flipper_length_mm) ┃ Max(bill_depth_mm) ┃ ┡━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━┩ │ float64 │ float64 │ ├─────────────────────────┼────────────────────┤ │ 200.915205 │ 21.5 │ └─────────────────────────┴────────────────────┘
Но aggregate действительно превосходно работает в сочетании с group_by.
group_by
group_by создает группировки строк, имеющих одинаковое значение для одного или нескольких столбцов.
Но сам по себе он не делает многого – вы можете сочетать его с aggregate для получения результата.
penguins.group_by("species").aggregate() ┏━━━━━━━━━━━┓ ┃ species ┃ ┡━━━━━━━━━━━┩ │ string │ ├───────────┤ │ Adelie │ │ Gentoo │ │ Chinstrap │ └───────────┘
Мы сгруппировали по столбцу species и передали ему «пустую» команду агрегирования. Результатом этого является столбец уникальных значений в столбце species.
Если мы добавим второй столбец к group_by, мы получим каждую уникальную пару значений в этих столбцах.
penguins.group_by(["species", "island"]).aggregate()
┏━━━━━━━━━━━┳━━━━━━━━━━━┓ ┃ species ┃ island ┃ ┡━━━━━━━━━━━╇━━━━━━━━━━━┩ │ string │ string │ ├───────────┼───────────┤ │ Adelie │ Torgersen │ │ Adelie │ Biscoe │ │ Adelie │ Dream │ │ Gentoo │ Biscoe │ │ Chinstrap │ Dream │ └───────────┴───────────┘
Теперь, если мы добавим функцию агрегирования, мы начинаем по-настоящему открывать для себя возможности.
penguins.group_by(["species", "island"]).aggregate(penguins.bill_length_mm.mean())
┏━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┓ ┃ species ┃ island ┃ Mean(bill_length_mm) ┃ ┡━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━┩ │ string │ string │ float64 │ ├───────────┼───────────┼──────────────────────┤ │ Adelie │ Torgersen │ 38.950980 │ │ Adelie │ Biscoe │ 38.975000 │ │ Adelie │ Dream │ 38.501786 │ │ Gentoo │ Biscoe │ 47.504878 │ │ Chinstrap │ Dream │ 48.833824 │ └───────────┴───────────┴──────────────────────┘
Добавив mean к aggregate, мы теперь имеем компактный способ вычисления агрегатов по каждой из уникальных групп в group_by. И мы можем вычислить столько агрегатов, сколько нам нужно.
penguins.group_by(["species", "island"]).aggregate(
[penguins.bill_length_mm.mean(), penguins.flipper_length_mm.max()]
) ┏━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃ species ┃ island ┃ Mean(bill_length_mm) ┃ Max(flipper_length_mm) ┃ ┡━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━┩ │ string │ string │ float64 │ int64 │ ├───────────┼───────────┼──────────────────────┼────────────────────────┤ │ Adelie │ Torgersen │ 38.950980 │ 210 │ │ Adelie │ Biscoe │ 38.975000 │ 203 │ │ Adelie │ Dream │ 38.501786 │ 208 │ │ Gentoo │ Biscoe │ 47.504878 │ 231 │ │ Chinstrap │ Dream │ 48.833824 │ 212 │ └───────────┴───────────┴──────────────────────┴────────────────────────┘
Если нам нужны более специфичные группы, мы можем добавить их в group_by.
penguins.group_by(["species", "island", "sex"]).aggregate(
[penguins.bill_length_mm.mean(), penguins.flipper_length_mm.max()]
) ┏━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃ species ┃ island ┃ sex ┃ Mean(bill_length_mm) ┃ Max(flipper_length_mm) ┃ ┡━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━┩ │ string │ string │ string │ float64 │ int64 │ ├─────────┼───────────┼────────┼──────────────────────┼────────────────────────┤ │ Adelie │ Torgersen │ male │ 40.586957 │ 210 │ │ Adelie │ Torgersen │ female │ 37.554167 │ 196 │ │ Adelie │ Torgersen │ NULL │ 37.925000 │ 193 │ │ Adelie │ Biscoe │ female │ 37.359091 │ 199 │ │ Adelie │ Biscoe │ male │ 40.590909 │ 203 │ │ Adelie │ Dream │ female │ 36.911111 │ 202 │ │ Adelie │ Dream │ male │ 40.071429 │ 208 │ │ Adelie │ Dream │ NULL │ 37.500000 │ 179 │ │ Gentoo │ Biscoe │ female │ 45.563793 │ 222 │ │ Gentoo │ Biscoe │ male │ 49.473770 │ 231 │ │ … │ … │ … │ … │ … │ └─────────┴───────────┴────────┴──────────────────────┴────────────────────────┘
Цепочки всех операций вместе
Мы уже объединили несколько вызовов Ibis. Мы использовали mutate для создания нового столбца и затем select для просмотра подмножества новой таблицы. Мы просто объединили group_by с aggregate.
Ничто не мешает нам объединить все эти концепции, чтобы задавать вопросы о данных.
Как насчёт:
- Какой была самая большая самка пингвина (по массе тела) на каждом острове в 2008 году?
penguins.filter((penguins.sex == "female") & (penguins.year == 2008)).group_by(
["island"]
).aggregate(penguins.body_mass_g.max()) ┏━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┓ ┃ island ┃ Max(body_mass_g) ┃ ┡━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━┩ │ string │ int64 │ ├───────────┼──────────────────┤ │ Biscoe │ 5200 │ │ Torgersen │ 3800 │ │ Dream │ 3900 │ └───────────┴──────────────────┘
- А как насчёт самой большой самца пингвина (по массе тела) на каждом острове для каждого года сбора данных?
penguins.filter(penguins.sex == "male").group_by(["island", "year"]).aggregate(
penguins.body_mass_g.max().name("max_body_mass")
).order_by(["year", "max_body_mass"]) ┏━━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━━┓ ┃ island ┃ year ┃ max_body_mass ┃ ┡━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━━┩ │ string │ int64 │ int64 │ ├───────────┼───────┼───────────────┤ │ Dream │ 2007 │ 4650 │ │ Torgersen │ 2007 │ 4675 │ │ Biscoe │ 2007 │ 6300 │ │ Torgersen │ 2008 │ 4700 │ │ Dream │ 2008 │ 4800 │ │ Biscoe │ 2008 │ 6000 │ │ Torgersen │ 2009 │ 4300 │ │ Dream │ 2009 │ 4475 │ │ Biscoe │ 2009 │ 6000 │ └───────────┴───────┴───────────────┘
Узнать больше
Это всё для этого краткого руководства. Если вы хотите узнать больше, ознакомьтесь с документацией Ibis.
© Copyright 2018–2024 Stichting DuckDB Foundation
Licensed under the MIT License.
https://duckdb.org/docs/guides/python/ibis.html