with - python dataframe groupby transform




O valor de groupby conta com os pandas de dataframe (3)

Eu tenho o seguinte dataframe:

df = pd.DataFrame([
    (1, 1, 'term1'),
    (1, 2, 'term2'),
    (1, 1, 'term1'),
    (1, 1, 'term2'),
    (2, 2, 'term3'),
    (2, 3, 'term1'),
    (2, 2, 'term1')
], columns=['id', 'group', 'term'])

Eu quero agrupá-lo por id e group e calcular o número de cada termo para este id, par de grupos.

Então, no final, eu vou conseguir algo assim:

Consegui alcançar o que eu queria, fazendo o loop de todas as linhas com df.iterrows() e criando um novo dataframe, mas isso é claramente ineficiente. (Se isso ajudar, eu conheço a lista de todos os termos de antemão e há ~ 10 deles).

Parece que eu tenho que agrupar por e, em seguida, contar valores, então eu tentei isso com df.groupby(['id', 'group']).value_counts() que não funciona porque value_counts opera na série groupby e não um quadro de dados.

De qualquer forma eu posso conseguir isso sem loop?


Em vez de lembrar de soluções demoradas, que tal o que os pandas criaram para você:

df.groupby(['id', 'group', 'term']).count()

Eu uso groupby e size

df.groupby(['id', 'group', 'term']).size().unstack(fill_value=0)

Cronometragem

1.000.000 linhas

df = pd.DataFrame(dict(id=np.random.choice(100, 1000000),
                       group=np.random.choice(20, 1000000),
                       term=np.random.choice(10, 1000000)))


Você pode usar a crosstab :

print (pd.crosstab([df.id, df.group], df.term))
term      term1  term2  term3
id group                     
1  1          2      1      0
   2          0      1      0
2  2          1      0      1
   3          1      0      0

Outra solução com groupby com size agregação, remodelando por unstack :

df.groupby(['id', 'group', 'term'])['term'].size().unstack(fill_value=0)

term      term1  term2  term3
id group                     
1  1          2      1      0
   2          0      1      0
2  2          1      0      1
   3          1      0      0

Horários :

df = pd.concat([df]*10000).reset_index(drop=True)

In [48]: %timeit (df.groupby(['id', 'group', 'term']).size().unstack(fill_value=0))
100 loops, best of 3: 12.4 ms per loop

In [49]: %timeit (df.groupby(['id', 'group', 'term'])['term'].size().unstack(fill_value=0))
100 loops, best of 3: 12.2 ms per loop




pandas-groupby