Это вторая часть серии статей. Вы можете найти первую часть здесь:



Введение

В этой серии статей я решил сравнить Python Pandas с SQL. Это оба популярных инструмента для управления данными, и их функциональность во многом пересекается. В этой статье мы рассмотрим агрегирование и группировку данных. Мы еще раз будем использовать набор данных Titanic, который можно найти на Kaggle для примеров в этой статье. Я рекомендую вам загрузить его и следить за максимальным сохранением. Также не забудьте в конце попробовать свои силы в решении практических задач. Ладно, приступим!

Агрегатные функции

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

SQL

Для выполнения агрегатных функций в SQL вы можете использовать AVG(), COUNT(), MIN(), MAX() и SUM() со столбцом, к которому вы хотите применить функцию в скобках. Следует помнить, что эти агрегатные функции игнорируют значения NULL. Вот как будет выглядеть созданная нами проблема.

SELECT MAX(fare), MIN(fare), AVG(age), SUM(survived)
FROM titanic

Помните, что столбец «Выжившие» имеет код 1 для тех, кто выжил, и 0 для тех, кто не выжил. Вот почему функция SUM() дает нам общее количество выживших.

Для этих агрегатных функций может оказаться полезным использовать ROUND() для получения более красивых результатов. Если бы мы хотели округлить результат столбца среднего возраста, например, до одного десятичного знака, это выглядело бы так: ROUND(AVG(age), 1). Если бы мы хотели округлить до ближайшего целого числа, это выглядело бы так: ROUND(AVG(age)).

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

Панды

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

titanic.fare.agg(['max','min'])
titanic.age.mean()
titanic.survived.sum()

agg() здесь давайте добавим список. Поскольку мы хотим найти максимальное и минимальное значение столбца тарифа, мы можем объединить это в одну строку кода с помощью метода agg().

Как упоминалось в примере SQL, вы можете округлить, чтобы результаты выглядели лучше. Для этого вы можете подключить round(). Первый параметр - это количество десятичных знаков, значение по умолчанию - 0. Например, округление до одного знака после запятой для среднего возраста будет titanic.age.mean().round(1).

Что-то действительно замечательное в Pandas - это метод describe(), который возвращает сводную таблицу по числовым столбцам. Код titanic.describe() возвращает приведенную ниже таблицу.

Это больше информации, чем требовалось технически, но все же очень полезно и требует всего лишь одной очень простой строчки кода. Вы также можете получить некоторую информацию о столбцах типа данных «объект» с помощью titanic.describe(include=”O”). Вот что вернут.

В Pandas гораздо больше агрегатных функций, чем в SQL, таких как медиана (median()), стандартное отклонение (std()) и дисперсия (var()). Метод agg() также обеспечивает еще большую гибкость, когда вы можете агрегировать на основе специально написанной функции, если хотите.

Группа по

Допустим, мы хотим найти агрегированные данные по мужчинам и женщинам каждого класса. Давайте найдем количество, средний возраст и количество выживших мужчин и женщин в каждом классе.

SQL

В SQL для этой цели используется предложение GROUP BY. Вот как бы это выглядело.

SELECT sex, pclass, COUNT(*), SUM(survived), AVG(age)
FROM titanic
GROUP BY sex, pclass

В этом примере, поскольку мы возвращаем столбцы, которые не являются агрегированными значениями (пол, pclass), код не будет работать без предложения GROUP BY, поскольку SQL не знает, как обрабатывать эти столбцы без него. При группировке по полу и классу агрегированные столбцы будут рассчитываться индивидуально для каждой комбинации пола и класса (женщины в первом классе, мужчины в первом классе, женщины во втором классе и т. Д.)

Панды

В Pandas есть метод groupby() для получения желаемых результатов. Таким же образом, как и раньше, мы можем запустить код, чтобы получить каждый отдельный фрагмент, который нам нужен, или мы можем запустить код, который содержит больше информации, чем нам нужно. Вот как бы выглядело получение информации по частям.

titanic.groupby(['sex', 'pclass']).survived.agg(['count', 'sum'])
titanic.groupby(['sex', 'pclass']).age.mean()

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

new_df = titanic.groupby(['sex', 'pclass'])[['survived', 'age']]
new_df.agg(['count', 'sum', 'mean'])

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

В некоторых случаях эта дополнительная информация может быть дополнительным бонусом интереса, в других случаях она может вызвать еще большую путаницу. Например, количество выживших и возраст различаются. Это связано с тем, что в столбце возраста есть нулевые значения, поэтому счетчики в оставшемся столбце являются истинными счетчиками, которые нам важны, поскольку нет нулевых значений. Но это может вызвать ненужную путаницу. С другой стороны, среднее значение в столбце «Выжившие» показывает процент выживших в каждой из групп, что представляет собой интересную информацию, которая повышает ценность анализа.

Проблемы с практикой

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

СТОП - ответы ниже

Вы пробовали каждую проблему, прежде чем искать ответ? Помните, что ожидается, что ваши ответы будут немного отличаться от моих, поскольку часто существует несколько способов решения.

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

SQL:

SELECT embarked, pclass, COUNT(*), AVG(fare)
FROM titanic
GROUP BY embarked, pclass

Панды:

titanic.groupby(['embarked', 'pclass']).fare.mean()
titanic.groupby(['embarked', 'pclass']).embarked.count()

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

SQL:

SELECT pclass, survived, MIN(age), MAX(age), AVG(age)
FROM titanic
GROUP BY pclass, survived

Панды:

titanic.groupby(['pclass','survived']).age.agg(['min','max','mean'])

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

SQL:

SELECT survived, AVG(fare), MIN(age), MAX(age)
FROM titanic
GROUP BY survived

Панды:

titanic.groupby('survived').age.agg(['min', 'max'])
titanic.groupby('survived').fare.mean()

Вывод

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