Используйте crosstab
и добавьте новый столбец с DataFrame.join
и агрегируйте sum
:
df = pd.crosstab(df['Commune'], df['Winner']).join(df.groupby('Commune')['Swing'].sum())
print (df)
PAM PJD UDF Swing
Commune
Madrid 2 1 0 1
Paris 2 1 1 3
Но если необходимо количество строк:
df1 = pd.crosstab(df['Commune'], df['Winner'], margins=True, margins_name='Total').iloc[:-1]
Или:
df = pd.crosstab(df['Commune'], df['Winner']).assign(Total= lambda x: x.sum(axis=1))
print (df1)
Winner PAM PJD UDF Total
Commune
Madrid 2 1 0 3
Paris 2 1 1 4
РЕДАКТИРОВАТЬ:
Если возможны другие столбцы, используйте агрегирование по first
, если все значения в группаха для turnout
используйте какую-нибудь другую агрегатную функцию, например mean
, sum
...:
df1 = (df.groupby('Commune')
.agg({'Swing':'sum', 'longitude':'first','latitude':'first','turnout':'mean'}))
print (df1)
Swing longitude latitude turnout
Commune
Madrid 1 10.435 -3.093 0.36690
Paris 3 12.323 12.093 0.40896
df = pd.crosstab(df['Commune'], df['Winner']).join(df1)
print (df)
PAM PJD UDF Swing longitude latitude turnout
Commune
Madrid 2 1 0 1 10.435 -3.093 0.36690
Paris 2 1 1 3 12.323 12.093 0.40896
Если хотите mean
всех столбцов без Swing
, то можно динамически создавать словарь:
d = dict.fromkeys(df.columns.difference(['Commune','Winner','Swing']), 'mean')
d['Swing'] = 'sum'
print (d)
{'latitude': 'mean', 'longitude': 'mean', 'turnout': 'mean', 'Swing': 'sum'}
df1 = df.groupby('Commune').agg(d)
print (df1)
latitude longitude turnout Swing
Commune
Madrid -3.093 10.435 0.36690 1
Paris 12.093 12.323 0.40896 3
df = pd.crosstab(df['Commune'], df['Winner']).join(df1)
print (df)
PAM PJD UDF latitude longitude turnout Swing
Commune
Madrid 2 1 0 -3.093 10.435 0.36690 1
Paris 2 1 1 12.093 12.323 0.40896 3