GroupBy в Pandas намного сложнее и мощнее, чем groupby в SQL.
Одной из популярных функций пакета Pandas является функция группировки. Я считаю, что почти каждый, кто использовал Pandas раньше, также должен использовать функцию groupby. Он так популярен, потому что эффективно дает обобщенные, но подробные результаты. Как описано в документе пакета Pandas,
Под «группировкой по» мы подразумеваем процесс, включающий один или несколько из следующих шагов:
Разделение данных на группы по некоторым критериям.
Применение функции к каждой группе независимо.
Объединение результатов в структуру данных. [1]
В SQL также есть функция группировки. Поэтому для тех, кто имеет опыт работы с SQL, изучение групповых функций в Python не является сложной задачей. Но дело в том, что groupby в Pandas может выполнять гораздо больший анализ, чем в SQL, и это делает groupby в Pandas общей, но важной функцией.
Причина, по которой groupby в Pandas более мощная, заключается в том, что второй шаг «Применение». В SQL большинство действий в шагах «Применение» связаны статистически, например min, max, count и т. Д. Однако в Pandas «Применение» может выполнять гораздо больше.
Из документа Панд,
На этапе применения нам может потребоваться одно из следующего:
Агрегирование: рассчитайте сводную статистику (или статистику) для каждой группы.
Преобразование: выполните некоторые вычисления для конкретных групп и верните объект с похожим индексом.
Фильтрация: отбросьте некоторые группы в соответствии с групповым вычислением, которое оценивает True или False. [1]
В этой статье я расскажу о некоторых групповых приложениях. Эти приложения не только показывают мне понимание данных, но также помогают мне определить, как я буду дальше анализировать данные.
Давай начнем.
В этой статье используются данные student-por.csv в Потребление алкоголя студентами от Kaggle. Вы можете скачать данные по этой ссылке.
# Input import pandas as pd data = pd.read_csv('student-por.csv') data.info() # Output <class 'pandas.core.frame.DataFrame'> RangeIndex: 649 entries, 0 to 648 Data columns (total 33 columns): school 649 non-null object sex 649 non-null object age 649 non-null int64 address 649 non-null object famsize 649 non-null object Pstatus 649 non-null object Medu 649 non-null int64 Fedu 649 non-null int64 Mjob 649 non-null object Fjob 649 non-null object reason 649 non-null object guardian 649 non-null object traveltime 649 non-null int64 studytime 649 non-null int64 failures 649 non-null int64 schoolsup 649 non-null object famsup 649 non-null object paid 649 non-null object activities 649 non-null object nursery 649 non-null object higher 649 non-null object internet 649 non-null object romantic 649 non-null object famrel 649 non-null int64 freetime 649 non-null int64 goout 649 non-null int64 Dalc 649 non-null int64 Walc 649 non-null int64 health 649 non-null int64 absences 649 non-null int64 G1 649 non-null int64 G2 649 non-null int64 G3 649 non-null int64 dtypes: int64(16), object(17) memory usage: 167.4+ KB
Шаг 1. Разделение данных
Первый шаг довольно простой - группировка данных на основе значения в одном или нескольких столбцах. Вам нужно только указать, как выполнять группировку. Большинство людей уже знают, что для группировки можно использовать имя столбца или список имен столбцов. Однако вы также можете передать функцию для группировки. Функция будет использовать значение индекса в качестве параметра и выполнять группировку. Для получения дополнительной информации, [2]
Объект, возвращаемый функцией groupby, - это «объект DataFrameGroupBy». После группировки вы можете использовать group
, чтобы увидеть группы.
#Groupby one column # Input data.groupby('school') # Output <pandas.core.groupby.generic.DataFrameGroupBy object at 0x0000024D28C9DF98> # Input data.groupby('school').groups # Output {'GP': Int64Index([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ...413, 414, 415, 416, 417, 418, 419, 420, 421, 422], dtype='int64', length=423), 'MS': Int64Index([423, 424, 425, 426, 427, 428, 429, 430, 431, 432, ...639, 640, 641, 642, 643, 644, 645, 646, 647, 648], dtype='int64', length=226)} # Groupby a function # Input def grouping(int): if int%10==0: return 'Group1' if int%5==0: return 'Group2' return 'Group3' data.groupby(grouping).groups # Output {'Group1': Int64Index([ 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 280, 290, 300, 310, 320, 330, 340, 350, 360, 370, 380, 390, 400, 410, 420, 430, 440, 450, 460, 470, 480, 490, 500, 510, 520, 530, 540, 550, 560, 570, 580, 590, 600, 610, 620, 630, 640], dtype='int64'), 'Group2': Int64Index([ 5, 15, 25, 35, 45, 55, 65, 75, 85, 95, 105, 115, 125,135, 145, 155, 165, 175, 185, 195, 205, 215, 225, 235, 245, 255, 265, 275, 285, 295, 305, 315, 325, 335, 345, 355, 365, 375, 385, 395, 405, 415, 425, 435, 445, 455, 465, 475, 485, 495, 505, 515, 525, 535, 545, 555, 565, 575, 585, 595, 605, 615, 625, 635, 645], dtype='int64'), 'Group3': Int64Index([ 1, 2, 3, 4, 6, 7, 8, 9, 11, 12,... 637, 638, 639, 641, 642, 643, 644, 646, 647, 648],dtype='int64', length=519)}
В приведенном выше примере с использованием функции для группировки индекс в кадре данных - это номер строки. Следовательно, строка назначается одной из трех групп на основе номера строки. Затем функция groupby группирует эти три группы.
Чтобы получить данные для каждой группы, вы можете затем использовать функцию get_group()
и ввести имя группы.
#Input data.groupby(grouping).get_group('Group1')
Кроме того, если вы хотите сгруппировать данные по столбцу, не являющемуся индексом, вы можете использовать для группировки вместе apply и лямбда-функции.
# Input data.groupby(data['famsize'].apply(lambda x: x.startswith('GT'))).get_group(False)
После группировки вы уже можете применить ряд функций вычисления или статистики. Например, size()
может дать вам количество строк для каждой группы; sum()
возвращает сумму для всех числовых столбцов для каждой группы. Чтобы узнать больше о применимых функциях, [3]
#Input data.groupby(data['famsize'].apply(lambda x: x.startswith('GT'))).size() #Output famsize False 192 True 457 dtype: int64
Шаг 2. Применение функции и объединение результатов
Пришло время осветить важную часть groupby. Функция Groupby в Pandas намного мощнее, чем в SQL, потому что вы можете использовать не только общие статистические функции, такие как min(), max(), mean(),...
, но также и множество более сложных функций. Вы также можете применять свои определенные функции. В следующем разделе я объясню эти три действия по отдельности.
Агрегация (агрегирование)
Простое объяснение агрегирования - это выполнение вычислений на основе ранее сгруппированных данных. Агрегирование применяется к каждой группе и возвращает соответствующий результат.
Некоторые общие вычисления похожи на sum
, min
, max
,… Вы можете выполнить вычисление для всех числовых столбцов, или вы также можете указать столбец для выполнения вычисления.
#Input mjob_gp = data.groupby('Mjob') mjob_gp.agg('mean')
#Input mjob_gp['age'].agg('mean') #Output Mjob at_home 16.955556 health 16.312500 other 16.802326 services 16.661765 teacher 16.583333 Name: age, dtype: float64
Менее широко известно об агрегировании, что вы можете одновременно выполнять несколько вычислений для одного или нескольких столбцов. Это полезно, если вы хотите исследовать статистику столбца.
#Input mjob_gp.agg({'age':['mean','max']})
Однако одна проблема заключается в том, что столбцы находятся в многоиндексном режиме, что не очень хорошо для дальнейшей обработки (и мне лично не нравится многоиндексность). Таким образом, мы можем сделать еще один шаг и включить pd.NamedAgg
(Новое в версии Pandas 0.25.0) в agg
function. Для получения дополнительной информации о pd.NamedAgg
, [4]
#Input mjob_gp.agg(avg_age=pd.NamedAgg(column='age', aggfunc='mean'), min_age=pd.NamedAgg(column='age', aggfunc='min'), max_age=pd.NamedAgg(column='age', aggfunc='max'))
Использование pd.NamedAgg
дает два преимущества. Первое преимущество - это, конечно, отсутствие мультииндекса для столбцов. И второе преимущество заключается в том, что вы можете самостоятельно определять имена столбцов.
Неудивительно, что вы также можете использовать при агрегировании пользовательские функции.
#Input def range_function(x): return max(x) - min(x) mjob_gp.agg(max_age = pd.NamedAgg(column='age',aggfunc='max'), min_age = pd.NamedAgg(column='age',aggfunc='min'), range_age = pd.NamedAgg(column='age',aggfunc=range_function),)
Преобразование (преобразование)
Вернемся к описанию трансформации,
Преобразование: выполните некоторые вычисления для конкретных групп и верните объект с похожим индексом.
Ключевой частью являются «групповые вычисления». Вычисления в разных группах различаются. Например, max
даст вам максимум столбца для каждой группы, но не для всего набора данных.
Другой характеристикой преобразования является то, что вычисление применяется к каждой строке и возвращает результаты с одинаковой длиной каждой группы, в отличие от агрегации с уменьшенной длиной. Если вы знакомы с оконной функцией в SQL, преобразование в Pandas аналогично этому. (PS: вы все еще не знаете оконную функцию в SQL?!?! Посмотрите мою предыдущую статью, которая поможет вам понять, почему оконная функция в SQL так важна)
#Input mjob_gp['G1','G2','G3'].transform(lambda x: (x-x.mean())/x.std())
В приведенном выше примере для каждой группы значения от G1 до G3 нормализованы на основе среднего значения и стандартного отклонения для соответствующей группы.
Фильтр
Из описания в пандах,
Вернуть копию DataFrame, исключая элементы из групп, которые не удовлетворяют логическому критерию, заданному функцией func. [5]
Вы можете использовать filter
функцию, чтобы отфильтровать любые группы, не удовлетворяющие критериям.
#Input mjob_gp.filter(lambda x: x['G1'].mean() > 12)
В приведенном выше примере возвращаются только Mjob в разделах «здоровье» и «учитель», поскольку их средние значения «G1» больше 12.
#Input mjob_gp['G1'].mean() #Output Mjob at_home 10.451852 health 12.395833 other 11.275194 services 11.610294 teacher 12.555556 Name: G1, dtype: float64
Закрытие
Функция Groupby в Pandas - удобный инструмент для выполнения большого количества анализов и преобразований данных. Я надеюсь, что эта статья поможет вам понять мощь и полезность groupby в Pandas. Я уверен, что теперь вы знаете больше о том, как использовать groupby в обычном анализе данных. Удачи с пандами и увидимся в следующий раз.
Другая моя статья
Добавьте это в закладки, если вы новичок в Python (особенно если вы изучаете Python самостоятельно)
Как использовать Pandas для анализа числовых данных?
Веб-парсинг Twitter с помощью Python Selenium (Часть 1)
Веб-парсинг Twitter с помощью Python Selenium (Часть 2)
Цитирование / Ссылка
[1]: Группировать по: разделить-применить-объединить