Ответ 1
Эквивалент
df %>% groupby(col1) %>% summarize(col2_agg=max(col2), col3_agg=min(col3))
является
df.groupby('col1').agg({'col2': 'max', 'col3': 'min'})
который возвращает
col2 col3
col1
1 5 -5
2 9 -9
Возвращаемый объект представляет собой pandas.DataFrame с индексом col1
и столбцами с именем col2
и col3
. По умолчанию, когда вы группируете свои данные, pandas устанавливает столбец (группы) группировки в качестве индекса для эффективного доступа и модификации. Однако, если вы этого не хотите, есть две альтернативы для установки col1
в качестве столбца.
-
Pass
as_index=False
:df.groupby('col1', as_index=False).agg({'col2': 'max', 'col3': 'min'})
-
Вызов
reset_index
:df.groupby('col1').agg({'col2': 'max', 'col3': 'min'}).reset_index()
оба дают
col1 col2 col3
1 5 -5
2 9 -9
Вы также можете передать несколько функций на groupby.agg
.
agg_df = df.groupby('col1').agg({'col2': ['max', 'min', 'std'],
'col3': ['size', 'std', 'mean', 'max']})
Это также возвращает DataFrame, но теперь для столбцов имеется MultiIndex.
col2 col3
max min std size std mean max
col1
1 5 1 1.581139 5 1.581139 -3 -1
2 9 0 3.535534 5 3.535534 -6 0
MultiIndex очень удобен для выбора и группировки. Вот несколько примеров:
agg_df['col2'] # select the second column
max min std
col1
1 5 1 1.581139
2 9 0 3.535534
agg_df[('col2', 'max')] # select the maximum of the second column
Out:
col1
1 5
2 9
Name: (col2, max), dtype: int64
agg_df.xs('max', axis=1, level=1) # select the maximum of all columns
Out:
col2 col3
col1
1 5 -1
2 9 0
Ранее (до версия 0.20.0) можно было использовать словари для переименования столбцов в вызове agg
. Например
df.groupby('col1')['col2'].agg({'max_col2': 'max'})
вернет максимум второго столбца как max_col2
:
max_col2
col1
1 5
2 9
Однако он был устарел в пользу метода переименования:
df.groupby('col1')['col2'].agg(['max']).rename(columns={'max': 'col2_max'})
col2_max
col1
1 5
2 9
Он может быть подробным для DataFrame, такого как agg_df
, определенного выше. Вы можете использовать функцию переименования, чтобы сгладить эти уровни в этом случае:
agg_df.columns = ['_'.join(col) for col in agg_df.columns]
col2_max col2_min col2_std col3_size col3_std col3_mean col3_max
col1
1 5 1 1.581139 5 1.581139 -3 -1
2 9 0 3.535534 5 3.535534 -6 0
Для таких операций, как groupby().summarize(newcolumn=max(col2 * col3))
, вы все равно можете использовать agg, сначала добавив новый столбец с assign
.
df.assign(new_col=df.eval('col2 * col3')).groupby('col1').agg('max')
col2 col3 new_col
col1
1 5 -1 -1
2 9 0 0
Это возвращает максимум для старых и новых столбцов, но, как всегда, вы можете нарезать это.
df.assign(new_col=df.eval('col2 * col3')).groupby('col1')['new_col'].agg('max')
col1
1 -1
2 0
Name: new_col, dtype: int64
С groupby.apply
это будет короче:
df.groupby('col1').apply(lambda x: (x.col2 * x.col3).max())
col1
1 -1
2 0
dtype: int64
Однако groupby.apply
рассматривает это как пользовательскую функцию, поэтому он не является векторизованным. До сих пор функции, которые мы передавали в agg
('min', 'max', 'min', 'size' и т.д.), Векторизованы и являются псевдонимами для этих оптимизированных функций. Вы можете заменить df.groupby('col1').agg('min')
на df.groupby('col1').agg(min)
, df.groupby('col1').agg(np.min)
или df.groupby('col1').min()
, и все они будут выполнять одну и ту же функцию. Вы не увидите такой же эффективности при использовании пользовательских функций.
Наконец, начиная с версии 0.20, agg
можно использовать непосредственно в DataFrames, без необходимости группировки в первую очередь. Примеры здесь.