Сумма значений с определенным условием

#python #pandas #numpy

#python #pandas #numpy

Вопрос:

Я хотел бы задать вопрос о pandas / python. Допустим, у меня есть два столбца. Я хочу найти совокупную сумму значений моего первого столбца, пока значение моего второго столбца не достигнет определенного значения. Я думаю, что было бы лучшим вариантом объяснить вопрос, используя только небольшой пример.

У меня есть:

  A    B
 1    0
 2    0
 2    0
 1    1
 2    0
 3    0
 3    0
 5    1
  

Я хочу:

  A.   B.   C
 1.   0.   1
 2.   0.   3 (1 2)
 2.   0.   5 (1 2 2)
 1.   1.   6 (1 2 2 1) So, cumulative sum should stop here, because B reaches 1 now. 
 2.   0.   2 So, cumulative sum should begin again.
 3.   0.   5 (2 3)
 3.   0.   8 (2 3 3)
 5.   1.   13 (2 3 3 5) So, cumulative sum should stop again, because B reaches 1 again.
  

Заранее благодарю вас за вашу помощь.

Ответ №1:

Используйте DataFrameGroupBy.cumsum с другим cumsum для групп:

 df['C'] = df.groupby(df['B'].eq(1).iloc[::-1].cumsum())['A'].cumsum()
#if only 0 and 1 values in B
#df['C'] = df.groupby(df['B'].iloc[::-1].cumsum())['A'].cumsum()
print (df)
   A  B   C
0  1  0   1
1  2  0   3
2  2  0   5
3  1  1   6
4  2  0   2
5  3  0   5
6  3  0   8
7  5  1  13
  

Подробные сведения:

Сравните по 1 и измените порядок путем индексации с iloc :

 print (df['B'].eq(1).iloc[::-1])
7     True
6    False
5    False
4    False
3     True
2    False
1    False
0    False
Name: B, dtype: bool
  

Создавайте группы с помощью Series.cumsum :

 print (df['B'].iloc[::-1].cumsum())
7    1
6    1
5    1
4    1
3    2
2    2
1    2
0    2
Name: B, dtype: int64
  

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

1. Очень простое и отличное решение. Большое вам спасибо!

2. могу ли я использовать тот же код для стандартного отклонения? Я попытался, однако, получил ошибку.

3. @Khalid — Вам нужен новый столбец, заполненный std ? Затем используйте df['C'] = df.groupby(df['B'].eq(1).iloc[::-1].cumsum())['A'].transform('std') . Если требуется агрегирование — df1= df.groupby(df['B'].eq(1).iloc[::-1].cumsum())['A'].std()