Условная сумма Python Pandas, оставляя другие значения на месте

#python #pandas #dataframe #sum #pandas-groupby

#python #pandas #фрейм данных #сумма #pandas-groupby

Вопрос:

Мой df таков:

 year    state     party         percentage 
1976    Arizona   republican    43.34
1976    Arizona   third party   0.21
1976    Arizona   democrat      54.01
1976    Arizona   third party   0.99
1976    Arizona   third party   .45
1978    Alabama   third party   6.01
1978    Alabama   republican    43.32
1978    Alabama   third party   0.82
1978    Alabama   democrat      55.06 
1978    Alabama   democrat      93.99
1978    Alabama   third party   0.80
  

Я хочу использовать .groupby , но суммировать строку только в том случае, если сторона является «третьей стороной». Вот мой код:

 g = df_senate.groupby(['year','state','party'], as_index=False)
g.apply(lambda x: x[x['party'] == 'third party']['percentage'].sum())
  

Это почти работает, но я получаю 0 для других значений «party», и он свертывает другие стороны. Я хочу сохранить дополнительные строки «демократ» и «республиканец» для каждого года / штата без суммирования. Я хочу, чтобы суммировалась только «третья сторона»:

 year  state       party          percentage
1976  Arizona     democrat       0.00
                  republican     0.00
                  third party    2.65
1978  Alabama     democrat       0.00
                  republican     0.00
                  third party    7.63
  

Также как мне сохранить его как фрейм данных? Ввод as_index=False .groupby не сработал. В итоге я хочу получить:

 year  state       party          percentage
1976    Arizona   republican    43.34
1976    Arizona   third party   2.65
1976    Arizona   democrat      54.01
1978    Alabama   third party   7.63
1978    Alabama   republican    43.32
1978    Alabama   democrat      55.06 
1978    Alabama   democrat      93.99
  

(На случай, если вам интересно, это данные о выборах в Сенат, и иногда государству приходится выбирать 2 сенатора, а не только одного, и мне не нужно, чтобы проценты суммировались более чем на 100%, потому что это было бы странно)

Заранее благодарю вас!

Ответ №1:

 df = (
        df.groupby(['year', 'state', 'party'])['percentage'].apply(
            lambda x: [x.sum()] if x.name[2] == 'third party' else list(x))
        .explode()
        .reset_index() 
      )

print(df)
  

С принтами:

    year    state        party percentage
0  1976  Arizona     democrat      54.01
1  1976  Arizona   republican      43.34
2  1976  Arizona  third party       1.65
3  1978  Alabama     democrat      55.06
4  1978  Alabama     democrat      93.99
5  1978  Alabama   republican      43.32
6  1978  Alabama  third party       7.63