Наука о данных

4 полезных трюка от Pandas Group

Универсальное решение для всех ваших вопросов об агрегации данных с помощью Pandas Groupby

В Python pandas — это широко используемая библиотека для анализа данных. Благодаря множеству встроенных функций и методов анализ данных становится быстрее и проще.

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

Вот где полезна функция pandas — groupby() — которая группирует данные на основе значений из категориального или нечислового столбца и помогает вам анализировать данные по этим вновь сформированным группам.

В моей одной из прошлых статей — 5 Pandas Group By Tricks You Should Know in Python — вы можете узнать, что такое groupby и как его использовать.

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

Я также прикрепил полный Jupyter-Notebook со всеми примерами в конце этой статьи.

Давайте начнем!

В этой статье я использую самый популярный набор данных из UC Irvine Machine Learning RepositoryIris, созданный R.A. Fisher и доступен по лицензии CC BY 4.0.

Давайте импортируем набор данных в pandas DataFrame — df

import pandas as pd
df = pd.read_csv("iris.data",
                 header=None,
                 names=["sepal_length", "sepal_width",
                        "petal_length","petal_width","class"])
df.head()

Это простой набор данных размером 150 x 5, содержащий информацию о 3 классах растения Iris.

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

Применение разных функций к разным столбцам

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

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

df.groupby('class')['sepal_length'].sum()

Это довольно просто.

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

Вот где в дело вступает функция agg(), которая используется для применения агрегатных функций к объекту pandas DataFrame groupby, полученному с помощью pandas.DataFrame.groupby.

Конечно, вам не нужно использовать groupby() несколько раз, вы можете создать один объект groupby и передать столбец и его агрегатную функцию как пару ключ-значение в функцию agg().

Давайте посмотрим, как это сделать.

Вот два столбца, к которым вы хотите применить агрегатные функции: sepal_length и sepal_width, а фактические агрегатные функции, которые вы хотите применить к этим столбцам, — это sum и mean.

Следовательно, пара ключ-значение, т.е. словарь, будет иметь вид

dict1 = {'sepal_length':'sum', 'sepal_width':'mean'}

Принимая во внимание, что объект groupby будет создан как:

groupby_object = df.groupby(["class"])

Затем вы можете применить функцию agg() к этому объекту groupby, как показано ниже:

groupby_object.agg(dict1)

Чтобы получить вывод вроде —

Ну, вам не нужно разбивать код на 3 отдельные строки, что я сделал просто для упрощения.

Вы получите точно такой же результат, объединив все в одну строку кода, как показано ниже.

df.groupby(["class"]).agg({'sepal_length':'sum', 'sepal_width':'mean'})

Расширяя ту же логику, вы можете применять несколько функций к одному и тому же столбцу, но немного по-другому.

Применение нескольких функций к одному столбцу

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

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

Фактические агрегатные функции, которые вы хотите применить к этому столбцу, — это min, max и median, которые вы должны передать в виде списка, как показано ниже.

df.groupby('class')['sepal_length'].agg(['min', 'max', 'median'])

Таким же образом вы можете применить несколько функций к нескольким столбцам одновременно.

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

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

df.groupby(["class"]).agg({'sepal_length':['min', 'max', 'median'],
                           'sepal_width':['min', 'max', 'median']})

В результате вы получите простой для понимания DataFrame.

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

Настройка имен столбцов агрегации

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

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

Продолжая приведенный выше пример, вы хотите применить функцию ‘min’ к столбцу sepal_length, поэтому кортеж будет (‘sepal_length’, ‘min’), и вы назначите этот кортеж столбцу с именем min_sepal_length, как показано ниже. .

min_sepal_length = ('sepal_length','min')

Точно так же вы можете создавать кортежи для всех агрегаций столбцов и назначать им собственные имена.

min_sepal_length = ('sepal_length','min')
max_sepal_length = ('sepal_length','max')
median_sepal_length = ('sepal_length','median')

min_sepal_width = ('sepal_width','min')
max_sepal_width = ('sepal_width','max')
median_sepal_width = ('sepal_width','median')

И, наконец, передайте их в функцию agg() через запятую, как показано ниже.

df.groupby(["class"]).agg(min_sepal_length = ('sepal_length','min'),
                          max_sepal_length = ('sepal_length','max'),
                          median_sepal_length = ('sepal_length','median'),
                          min_sepal_width = ('sepal_width','min'),
                          max_sepal_width = ('sepal_width','max'),
                          median_sepal_width = ('sepal_width','median'))

Быстро это!

Теперь это выглядит намного упрощенным и легко читаемым выводом.

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

Применение пользовательских или определяемых пользователем функций

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

Теперь вы можете применить эти пользовательские или пользовательские функции к сгруппированным данным, используя метод agg.

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

def my_range(x):
    return x.max() - x.min()

А теперь вы хотите получить диапазон длины чашелистика, ширины чашелистика, длины лепестка и ширины лепестка растения ирис, разделенного по его классу.

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

df.groupby(["class"]).agg({'sepal_length':my_range,
                           'sepal_width':my_range,
                           'petal_length':my_range,
                           'petal_width':my_range})

Это быстро даст вам вывод как —

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

Поэтому здесь имеет смысл добавить больше контекста, чего можно добиться, добавив максимальные и минимальные значения для каждого столбца.

Интересно, что вы также можете комбинировать пользовательские функции со встроенными функциями и применять их к нескольким столбцам в функции agg().

Возьмем другой пример.

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

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

df.groupby(["class"]).agg({'sepal_length':['min', 'max', my_range],
                           'sepal_width':['min', 'max', my_range],
                           'petal_length':['min', 'max', my_range],
                           'petal_width':['min', 'max', my_range]})

Чтобы получить быстрый вывод как —

Интересно, правда?

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

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

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

my_range.__name__ = 'Max - Min'

А затем повторно примените функцию my_range ко всем необходимым столбцам, например,

df.groupby(["class"]).agg({'sepal_length':['min', 'max', my_range],
                           'sepal_width':['min', 'max', my_range],
                           'petal_length':['min', 'max', my_range],
                           'petal_width':['min', 'max', my_range]})

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

Вот и все об агрегации данных с помощью pandas groupby! 🏆

Я надеюсь, что вы нашли эту статью полезной и сохранили ее как универсальное решение для случаев использования pandas .groupby().

Знание этих гибких функций агрегации данных с помощью pandas .groupby(), безусловно, может повысить вашу производительность. Это также помогает вам агрегировать и представлять данные лучше и проще для понимания.

Хотите прочитать больше историй на Medium??

💡 Рассмотрите вариант Стать участником Medium, чтобы получить неограниченный доступ к историям на Medium и ежедневным интересным дайджестам Medium. Я получу небольшую часть вашего гонорара и никаких дополнительных затрат для вас.

💡 Не забудьте Подписаться на мою рассылку, чтобы не пропустить новую статью о руководствах, хитростях и советах по науке о данных, SQL и Python.

💡 Вот полный блокнот со всеми примерами.

Спасибо, что прочитали!