pandas применить пользовательскую функцию к сгруппированному кадру данных в нескольких столбцах - PullRequest
2 голосов
/ 10 апреля 2020

Я хотел бы применить функцию f1 по группам к фрейму данных:

import pandas as pd 
import numpy as np
data = np.array([['id1','id2','u','v0','v1'],
                ['A','A',10,1,7],
                ['A','A',10,2,8],
                ['A','B',20,3,9],
                ['B','A',10,4,10],
                ['B','B',30,5,11],
                ['B','B',30,6,12]])
z = pd.DataFrame(data = data[1:,:], columns=data[0,:])

def f1(u,v):
    return u*np.cumprod(v)

Результат функции зависит от столбца u и столбцов v0 или v1 (это может быть несколько тысяч, потому что я Я делаю симуляцию на многих путях).

Результат должен быть таким

    id1 id2 new_v0  new_v1
0   A   A   10  70
1   A   A   20  560
2   A   B   60  180
3   B   A   40  100
4   B   B   150 330
5   B   B   900 3960

Я пытался для начала output = z.groupby(['id1', 'id2']).apply(lambda x: f1(u = x.u,v =x.v0)), но я даже не могу получить результат только с одним столбцом.

Большое спасибо!

Ответы [ 3 ]

2 голосов
/ 10 апреля 2020

Вы можете отфильтровать имена столбцов, начиная с v, создать список и передать их в groupby:

v_cols = z.columns[z.columns.str.startswith('v')].tolist()

z[['u']+v_cols] = z[['u']+v_cols].apply(pd.to_numeric)

out = z.assign(**z.groupby(['id1','id2'])[v_cols].cumprod()
                .mul(z['u'],axis=0).add_prefix('new_'))
print(out)

  id1 id2   u  v0  v1  new_v0  new_v1
0   A   A  10   1   7      10      70
1   A   A  10   2   8      20     560
2   A   B  20   3   9      60     180
3   B   A  10   4  10      40     100
4   B   B  30   5  11     150     330
5   B   B  30   6  12     900    3960
2 голосов
/ 10 апреля 2020

То, как вы создаете свой фрейм данных, сделает numeric в object, мы сначала конвертируем, затем используем groupby + cumprod

z[['u','v0','v1']]=z[['u','v0','v1']].apply(pd.to_numeric)
s=z.groupby(['id1','id2'])[['v0','v1']].cumprod().mul(z['u'],0)
#z=z.join(s.add_prefix('New_'))
    v0    v1
0   10    70
1   20   560
2   60   180
3   40   100
4  150   330
5  900  3960
0 голосов
/ 10 апреля 2020

Если вы хотите обрабатывать столбцы более 2 v, лучше не ссылаться на них.

(
    z.apply(lambda x: pd.to_numeric(x, errors='ignore'))
    .groupby(['id1', 'id2']).apply(lambda x: x.cumprod().mul(x.u.min()))
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...