Как сгруппировать строки, сосчитать в одном столбце и сделать сумму в другом? - PullRequest
1 голос
/ 23 октября 2019

Я хочу сгруппировать строки в CSV-файле, сосчитать в одном столбце и добавить в другом.

Например, для следующего я хотел бы сгруппировать строки в Commune, чтобы сделать столбцы изwinner с количеством и столбцом Swing с суммой

Commune Winner Swing longitude latitude turnout
Paris   PAM    1     12.323    12.093   0.3242
Paris   PJD    0     12.323    12.093   0.1233
Paris   PAM    1     12.323    12.093   0.534
Paris   UDF    1     12.323    12.093   0.65434
Madrid  PAM    0     10.435    -3.093   0.3423
Madrid  PAM    1     10.435    -3.093   0.5234
Madrid  PJD    0     10.435    -3.093   0.235

Как группировать строки, иметь столбец в одном столбце и сумму в другом?

Commune PAM    PJD    UDF    Swing
Paris   3      1      1      3
Madrid  2      1      0      1

Пока я пытался попробовать:

g = df.groupby('Commune').Winner
pd.concat([g.apply(list), g.count()], axis=1, keys=['members', 'number'])

Но он возвращает:

    members number
Commune     
Paris   [PAM, PJD, PAM, UDF] 4
Madrid  [PAM, PAM, UDF] 3

Ответы [ 3 ]

2 голосов
/ 23 октября 2019

Это должно сделать это:

pd.pivot_table(df, values='Swing', index='Commune', columns='Winner', aggfunc='count').fillna(0).join(df.groupby('Commune')['Swing'].sum())

#         PAM  PJD  UDF  Swing
#Commune                      
#Madrid   2.0  1.0  0.0      1
#Paris    2.0  1.0  1.0      3
2 голосов
/ 23 октября 2019

Используйте 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
0 голосов
/ 23 октября 2019

Вот как я это сделал.

df_a = pd.pivot_table(df, values='Swing', index='Commune', columns='Winner', aggfunc='count', fill_value =0)
df_b = df.groupby('Commune')[['Swing']].sum()
output_df = df_a.join(df_b)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...