Pandas groupby принимает накопленную сумму до тех пор, пока порог не будет хотя бы достигнут (или превышен одной записью) - PullRequest
0 голосов
/ 26 сентября 2019

Как мы можем накапливать записи (накопленную сумму) до минимального порога, определяемого другим значением в кадре данных?Цель состоит в том, чтобы хотя бы достичь или превысить пороговое значение, а затем прекратить накопление в дальнейшем.Это групповая операция с использованием Pandas.

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

Пример кадра данных:

import pandas as pd

data = [
{'a':'z', 'b': 5, 'c': 15}, {'a':'z', 'b': 10, 'c': 15},
'a':'z', 'b': 2, 'c': 15},
{'a': 'x', 'b': 10, 'c':31}, {'a':'x', 'b': 20, 'c': 31}, {'a':'x',
'b': 5, 'c': 31, {'a':'x', 'b': 9, 'c': 31}
] 
df = pd.DataFrame(data) 

df:

    a   b   c
0   z   5   15
1   z   10  15
2   z   2   15
3   x   10  31
4   x   20  31
5   x   5   31
6   x   9   31

Уравнение, которое я могу визуализировать (но оно неверно):

df[df.groupby(by='a')['b'].cumsum()<=df['c']] 

    a   b   c
0   z   5   15
1   z   10  15
3   x   10  31
4   x   20  31

, но пока это работает для группыz (т. е. 5 + 10 = 15), он не работает для группы xb / c (10 + 20) <31.Мне нужно <em>по крайней мере встретить 31, поэтому следует также выбрать следующую запись (т. Е. (10 + 20 + 5) соответствует или превысит 31, а затем прекратить накапливать дальше.

IsЕсть ли способ применить накопительную операцию, которая будет соответствовать или превосходить по одной записи, эталон?

Ожидаемый / желаемый результат:

    a   b   c
0   z   5   15
1   z   10  15
3   x   10  31
4   x   20  31
5   x   5   31

Дляпервая группа (z), столбец B кумулятивно суммируется как минимум с col C (15) путем выбора первых двух записей, т. е. 5 + 10 = 15.

Для второй группы (x) столбец B кумулятивно суммируетсяпо крайней мере, на C (31), выбрав первые три записи записей, т. е. 10 + 20 + 5 - первая запись, которая соответствует или превышает 35. Остановитесь здесь и не продолжайте накапливать записи.

1 Ответ

0 голосов
/ 26 сентября 2019

Здесь я использую np.sign -1 означает меньше, 0 означает равный, 1 означает больше

d={x : y for x , y in df.groupby(np.sign(df.groupby('a').b.cumsum()-df.c))}
d
Out[30]: 
{-1:    a   b   c
 0  z   5  15
 3  x  10  31
 4  x  20  31, 0:    a   b   c
 1  z  10  15, 1:    a  b   c
 2  z  2  15
 5  x  5  31}

Чтобы получить d[0], d[1],d[-1]

...