Есть ли способ вычислить совокупную сумму в Python, гарантируя, что одни и те же значения имеют одинаковое максимальное значение суммы

#python #pandas

#python #pandas

Вопрос:

У меня есть столбец частоты в моем фрейме данных.

 frequency
1
1
1
1
2
2
3
4
5
5
5
5
  

Я хотел бы вычислить для него совокупную сумму, гарантируя, что все одинаковые значения частоты имеют одинаковое максимальное значение совокупной суммы, вот так

 frequency cumsum
1         35
1         35
1         35
1         35
2         31
2         31
3         27
4         24
5         20
5         20
5         20
5         20
  

Я могу сделать это в Google bigquery с помощью этого синтаксиса

 select 
frequency, 
sum(frequency) over (order by frequency desc) as cumsum
from `project1.dataset1.table1`
  

Я пробовал это в python

 df['cumsum'] = df['frequency'].sort_values(ascending=False).cumsum()
  

Что дает мне это

 frequency cumsum
1          5
1          4
1          3
1          2
2         31
2         29
3         27
4         24
5         20
5         15
5         10
5          5
  

Итак, я попытался добавить этот синтаксис:

 df['max_cumsum'] = df['frequency'].apply(lambda x: df[df['frequency'] == x]['cumsum'].max())
  

но это выполняется вечно. Я явно делаю что-то не так здесь. Пожалуйста, бросьте мне спасательный круг

Комментарии:

1. почему cumsum превышение частоты 1 5 ? разве это не должно быть 35 ?

2. Это должно быть да… позвольте мне отредактировать это … сейчас 2:45 утра в Южной Африке. Я немного сонный

Ответ №1:

Вы можете попробовать

 df['New'] = df.groupby('frequency')['cumsum'].transform('max')
  

Ответ №2:

Давайте попробуем map :

 df['cumsum'] = df['frequency'].map(df['frequency'].groupby(df['frequency']).sum()
                  .sort_index(ascending=False)
                  .cumsum() 
               )
  

Вывод:

     frequency  cumsum
0           1      35
1           1      35
2           1      35
3           1      35
4           2      31
5           2      31
6           3      27
7           4      24
8           5      20
9           5      20
10          5      20
11          5      20