web-dev-qa-db-fra.com

Je veux créer une colonne de value_counts dans mon cadre de données pandas

Je connais mieux R, mais je voulais voir s’il existait un moyen de le faire avec des pandas. Je souhaite créer un nombre de valeurs uniques à partir de l'une de mes colonnes de structure de données, puis ajouter une nouvelle colonne avec ces nombres à mon cadre de données d'origine. J'ai essayé plusieurs choses. J'ai créé une série de pandas puis calculé les comptes avec la méthode value_counts. J'ai essayé de fusionner ces valeurs dans mon cadre de données d'origine, mais les clés sur lesquelles je souhaite fusionner se trouvent dans l'index (ix/loc). Toute suggestion ou solution serait appréciée

Color Value
Red   100
Red   150
Blue  50

et je voulais retourner quelque chose comme

Color Value Counts
Red   100   2
Red   150   2 
Blue  50    1
33
user2592989
df['Counts'] = df.groupby(['Color'])['Value'].transform('count')

Par exemple,

In [102]: df = pd.DataFrame({'Color': 'Red Red Blue'.split(), 'Value': [100, 150, 50]})

In [103]: df
Out[103]: 
  Color  Value
0   Red    100
1   Red    150
2  Blue     50

In [104]: df['Counts'] = df.groupby(['Color'])['Value'].transform('count')

In [105]: df
Out[105]: 
  Color  Value  Counts
0   Red    100       2
1   Red    150       2
2  Blue     50       1

Notez que transform('count') ignore les NaN. Si vous voulez compter les NaN, utilisez transform(len)


Pour l'éditeur anonyme: Si vous obtenez une erreur lors de l'utilisation de transform('count'), cela peut être dû à votre version de Pandas trop ancienne. Ce qui précède fonctionne avec les pandas version 0.15 ou plus récente.

42
unutbu

Ma pensée initiale consisterait à utiliser la compréhension de liste comme indiqué ci-dessous, mais, comme cela a été souligné dans le commentaire, cette méthode est plus lente que les méthodes groupby et transform Je laisserai cette réponse pour démontrer CE QU'IL NE FAUT PAS FAIRE :

In [94]: df = pd.DataFrame({'Color': 'Red Red Blue'.split(), 'Value': [100, 150, 50]})
In [95]: df['Counts'] = [sum(df['Color'] == df['Color'][i]) for i in xrange(len(df))]
In [96]: df
Out[100]: 
  Color  Value  Counts
0   Red    100       2
1   Red    150       2
2  Blue     50       1

[3 rows x 3 columns]

La méthode de @ unutbu est compliquée pour les DataFrames à plusieurs colonnes, ce qui simplifie le code. Si vous travaillez avec un petit bloc de données, cela est plus rapide (voir ci-dessous), mais sinon, vous devez utiliserPASuse this. 

In [97]: %timeit df = pd.DataFrame({'Color': 'Red Red Blue'.split(), 'Value': [100, 150, 50]}); df['Counts'] = df.groupby(['Color']).transform('count')
100 loops, best of 3: 2.87 ms per loop
In [98]: %timeit df = pd.DataFrame({'Color': 'Red Red Blue'.split(), 'Value': [100, 150, 50]}); df['Counts'] = [sum(df['Color'] == df['Color'][i]) for i in xrange(len(df))]
1000 loops, best of 3: 1.03 ms per loop
2
Steven C. Howell

Une autre option:

    z = df['Color'].value_counts 

    z1 = z.to_dict() #converts to dictionary

    df['Count_Column'] = df['Color'].map(z1) 

Cette option vous donnera une colonne avec les valeurs répétées des comptes, correspondant à la fréquence de chaque valeur dans la colonne 'Couleur'.

1
ZakS