Comment faire une concaténation cumulative dans une trame de données pandas? J'ai trouvé qu'il existe un certain nombre de solutions dans R, mais je ne les trouve pas en python.

Voici le problème: supposons que nous ayons une trame de données: avec des colonnes: date et name:

import pandas as pd

d = {'date': [1,1,2,2,3,3,3,4,4,4], 'name':['A','B','A','C','A','B','B','A','B','C']}
df = pd.DataFrame(data=d)

Je veux obtenir CUM_CONCAT, qui est une date de regroupement concaténée cumulative:

    date name  CUM_CONCAT
0     1    A      [A]
1     1    B      [A,B]
2     2    A      [A]
3     2    C      [A,C]
4     3    A      [A]
5     3    B      [A,B]
6     3    B      [A,B,B]
7     4    A      [A]
8     4    B      [A,B]
9     4    C      [A,B,C]

Jusqu'à présent, j'ai essayé:

temp = df.groupby(['date'])['name'].apply(list)
df = df.join(temp, 'date', rsuffix='_cum_concat')

Et ce que j'ai c'est:

    date name  CUM_CONCAT
0     1    A      [A,B]
1     1    B      [A,B]
2     2    A      [A,C]
3     2    C      [A,C]
4     3    A      [A,B,B]
5     3    B      [A,B,B]
6     3    B      [A,B,B]
7     4    A      [A,B,C]
8     4    B      [A,B,C]
9     4    C      [A,B,C]

Je sais qu'il y a des fonctions .rolling et cumsum, qui sont similaires à ce dont j'ai besoin, mais elles sont principalement pour la somme cumulée et non pour la concaténation.

Toute aide serait appréciée!!!

0
FF0605 12 mars 2019 à 01:35

2 réponses

Meilleure réponse

J'ai trouvé une solution comme suit:

En termes de temps d'exécution, les deux solutions (moi et @ Wen-Ben) semblent similaires, son code est plus court

from itertools import accumulate

def cum_concat(x):
    return list(accumulate(x))
f = lambda x: cum_concat([[i] for i in x])
b =df.groupby(['date'])['name'].apply(f)
df['CUM_CONCAT']=[item for sublist in b for item in sublist]

df
Out: 
   date name CUM_CONCAT
0     1    A        [A]
1     1    B     [A, B]
2     2    A        [A]
3     2    C     [A, C]
4     3    A        [A]
5     3    B     [A, B]
6     3    B  [A, B, B]
7     4    A        [A]
8     4    B     [A, B]
9     4    C  [A, B, C]
0
FF0605 12 mars 2019 à 04:33

pandas rolling ne prendra pas en charge object, vous aurez donc peut-être besoin

df['CUM_CONCAT']=[y.name.tolist()[:z+1] for x, y in df.groupby('date')for z in range(len(y))]
df
Out[33]: 
   date name CUM_CONCAT
0     1    A        [A]
1     1    B     [A, B]
2     2    A        [A]
3     2    C     [A, C]
4     3    A        [A]
5     3    B     [A, B]
6     3    B  [A, B, B]
7     4    A        [A]
8     4    B     [A, B]
9     4    C  [A, B, C]
3
BENY 11 mars 2019 à 22:59