Функция Analyti c Sliding Windows в Python Pandas - PullRequest
0 голосов
/ 01 марта 2020

Есть таблица:

list_1= [['2016-01-01',1,'King', 1000],    
        ['2016-01-02',1,'King', -200],    
        ['2016-01-03',1,'King', 100],    
        ['2016-01-04',1,'King',-400],    
        ['2016-01-05',1,'King', 200],    
        ['2016-01-06',1,'King',  -200],    
        ['2016-01-01',2,'Smith',  1000],    
        ['2016-01-02',2,'Smith',  -300],    
        ['2016-01-03',2,'Smith',  -600],    
        ['2016-01-04',2,'Smith',  100],    
        ['2016-01-05',2,'Smith',  -100]]
labels=['a_date','c_id','c_name','c_action']
df=pd.DataFrame(list_1,columns=labels)
df

OUT:

    a_date       c_id   c_name  c_action
0   2016-01-01     1    King    1000
1   2016-01-02     1    King    -200
2   2016-01-03     1    King    100
3   2016-01-04     1    King    -400
4   2016-01-05     1    King    200
5   2016-01-06     1    King    -200
6   2016-01-01     2    Smith   1000
7   2016-01-02     2    Smith   -300
8   2016-01-03     2    Smith   -600
9   2016-01-04     2    Smith   100
10  2016-01-05     2    Smith   -100

Нужно получить таблицу:

a_date      c_id    c_name  c_amount    Balance
2016-01-01     1    King    1000        1000
2016-01-02     1    King    -200        800
2016-01-03     1    King    100         900
2016-01-04     1    King    -400        500
2016-01-05     1    King    200         700
2016-01-06     1    King    -200        500
2016-01-01     2    Smith   1000        1000
2016-01-02     2    Smith   -300        700
2016-01-03     2    Smith   -600        100
2016-01-04     2    Smith   100         200
2016-01-05     2    Smith   -100        100

Так что мне нужно сделать столбец "Баланс" с накопительным сумма после каждого действия для каждого клиента. Этот эквивалент для SQL запроса:

SELECT *,
        SUM(c_amount) OVER (PARTITION BY c_id ORDER BY a_date) AS 'Balance'
FROM account_actions

Для обоих клиентов решение несложное, можно разделить таблицу на c_id, суммировать и консолидировать обратно. Но это должно быть динамическое решение c для 10000 клиентов ...

1 Ответ

1 голос
/ 01 марта 2020

Как прокомментировал @Vaishali, это groupby и cumsum. Возможно, вы захотите сделать sort_values, чтобы убедиться, что данные отсортированы по порядку, хотя это уже выглядит так:

# sort by `c_id` and `a_date`
df = df.sort_values(['c_id','a_date'])

df['balance'] = df.groupby('c_id')['c_action'].cumsum()

Вывод:

        a_date  c_id c_name  c_action  balance
0   2016-01-01     1   King      1000     1000
1   2016-01-02     1   King      -200      800
2   2016-01-03     1   King       100      900
3   2016-01-04     1   King      -400      500
4   2016-01-05     1   King       200      700
5   2016-01-06     1   King      -200      500
6   2016-01-01     2  Smith      1000     1000
7   2016-01-02     2  Smith      -300      700
8   2016-01-03     2  Smith      -600      100
9   2016-01-04     2  Smith       100      200
10  2016-01-05     2  Smith      -100      100
...