Подробное объяснение того, как работает groupby, поможет вам лучше понять его.

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

Я хочу, чтобы вы представили, что просыпаетесь одним суматошным утром и начинаете просматривать свою подписку на Нью-Йорк Таймс, чтобы просмотреть некоторые данные (если вы никогда этого не сделаете, просто подшутите над мной на секунду). . Вы устали, ваши глаза едва открыты, а ваши умственные способности все еще разогреваются. Вам просто нужно быстрое и легкое для понимания понимание происходящего в данный момент.

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

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

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

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

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

Давайте углубимся в это.

Краткий обзор Groupby

Лучший способ понять groupby — на примере. Допустим, у нас есть следующий небольшой набор данных под названием people, который содержит информацию о поле, возрасте, росте и весе людей:

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

people.groupby('Sex').mean()

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

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

def sum_of_squares(arr):
    return sum([item * item for item in arr)])
people.groupby('Sex')[['Age']].agg(sum_of_squares)

Некоторые ключевые моменты из приведенного выше примера:

  • В нашей пользовательской функции sum_of_squares мы используем понимание списка [1, 2] для итеративного возведения в квадрат всех элементов перед их суммированием.
  • Вы заметите, что функция принимает массив. Это связано с тем, что когда мы группируем по 'Sex' и извлекаем 'Age', мы эффективно сохраняем все возрасты для каждой соответствующей группы (в данном случае 'Male' и 'Female') в массиве (или технически, в объекте серии [3]). . Затем функция агрегации принимает этот массив и объединяет его значения в единое окончательное значение для каждой группы, отображаемое в выходном кадре данных. Мы получим более полное представление об этом в следующей части статьи.
  • Использование двойных скобок для извлечения столбца 'Age' — это небольшая синтаксическая хитрость, которая позволяет нам возвращать вывод в виде DataFrame вместо Series.

И на этом мы рассмотрели все, что нам нужно о groupby, чтобы правильно понять, что происходит ниже уровня абстракции. Теперь мы готовы пойти глубже.

«Волшебство» Groupby

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

Код: people.groupby('Sex').mean()

До:

После:

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

  1. Исходный, неизмененный DataFrame (картинка «До»).
  2. Преобразованный кадр данных, который группирует все уникальные метки в интересующем столбце вместе со связанными значениями в других столбцах.
  3. Окончательный кадр данных, в котором собраны значения, так что каждая группа имеет единственное значение (изображение «После»).

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

Первая попытка может заключаться в попытке отобразить данные после вызова groupby, но до вызова функции агрегации (в нашем случае mean):

people.groupby('Sex')

Хм, ладно — значит, все пошло не так, как планировалось. Нам просто дается строковое представление буквального объекта GroupBy, как это реализовано в Pandas. Оказывается, чтобы увидеть фактические данные, разделенные по группам, нам нужно использовать связанную с объектом функцию get_group:

people_grouped_by_sex = people.groupby('Sex')
for group in people['Sex'].unique():
    display(people_grouped_by_sex.get_group(group))

Давайте разберем это:

  • Во-первых, мы сохраняем объект GroupBy в переменной people_grouped_by_sex.
  • Затем мы используем цикл для перебора всех уникальных меток столбца 'Sex', которые, как мы знаем, образуют уникальные группы нашего объекта GroupBy. Обратите внимание, что сработало бы и просто перебор жестко закодированного списка, такого как ['Male', 'Female'] , но я намеренно написал приведенный выше код, чтобы продемонстрировать, как вы можете обобщить этот метод на более крупный набор данных — особенно тот, в котором вы, возможно, не знаете все уникальные групповые метки заранее.
  • Наконец, мы используем метод get_group объекта GroupBy для доступа к DataFrame для каждой соответствующей группы — мне нравится называть их подкадры или мини-DataFrames, хотя я упомяну, что это ни в коем случае не стандартные термины. Функция display используется в Jupyter Notebooks [4] для вывода любого объекта, который вы ей передаете, в красивом, удобочитаемом формате.

Итак, теперь мы можем видеть, что происходит на среднем этапе: Pandas берет DataFrame и разбивает его на несколько меньших, каждый из которых содержит данные для одной из групповых меток в столбце, по которому мы группируемся. Затем значения из этих подкадров объединяются, чтобы получить наш окончательный кадр данных.

Например, в первом подкадре выше (для группы 'Male') значения в столбце 'Age' равны 44, 30, 24, и 18. Среднее значение этих чисел равно 29.00, именно то значение, которое мы видим в нашем окончательном выходном DataFrame после вызова функции mean для нашего объекта GroupBy. Точно так же рассчитываются и другие значения.

Вот и все — тайна groupby больше не тайна.

Несколько заключительных советов и мыслей

Я закончу несколькими общими советами, которые следует помнить, когда в следующий раз вы будете иметь дело с groupby, будь то для себя или для объяснения другому:

  • Простота. Целью использования groupby должно быть упрощение ваших данных, а не их усложнение.
  • Фокус. Хотя можно сгруппировать несколько столбцов, обычно рекомендуется начинать медленно и сосредоточиться на получении целенаправленной информации. Вы можете многое сделать даже с одним столбцом за раз.
  • Адаптируемость. Не зацикливайтесь на этом уникальном решении, так как в зависимости от вашей ситуации могут быть варианты получше. Есть другие способы агрегировать данные в Pandas.

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

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

И на этом я прощаюсь с вами до следующего раза. Удачной группировки!

Хотите преуспеть в Python? Получите эксклюзивный бесплатный доступ к моим простым и понятным руководствам здесь. Хотите читать неограниченное количество историй на Medium? Зарегистрируйтесь по моей реферальной ссылке ниже!



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

Рекомендации

[1] https://towardsdatascience.com/whats-in-a-list-comprehension-c5d36b62f5
[2] https://levelup.gitconnected.com/whats-in-a-list- понимание-часть-2-49d34bada3f5
[3] https://pandas.pydata.org/docs/reference/api/pandas.Series.html
[4] https:// levelup.gitconnected.com/whats-in-a-jupyter-notebook-windows-edition-1f69c290a280