web-dev-qa-db-fra.com

Python Pandon: tableau croisé dynamique avec aggfunc = compte unique distinct

df2 = pd.DataFrame({'X' : ['X1', 'X1', 'X1', 'X1'], 'Y' : ['Y2','Y1','Y1','Y1'], 'Z' : ['Z3','Z1','Z1','Z2']})

    X   Y   Z
0  X1  Y2  Z3
1  X1  Y1  Z1
2  X1  Y1  Z1
3  X1  Y1  Z2

g=df2.groupby('X')

pd.pivot_table(g, values='X', rows='Y', cols='Z', margins=False, aggfunc='count')

Traceback (appel le plus récent en dernier): ... AttributeError: objet 'Index' n'a pas d'attribut 'index'

Comment obtenir un tableau croisé dynamique avec le nombre de valeurs uniques d'une colonne DataFrame pour deux autres colonnes?
Y a-t-il aggfunc pour le compte unique? Devrais-je utiliser np.bincount()?

NB Je suis au courant de 'Series' values_counts() mais j'ai besoin d'un tableau croisé dynamique.


EDIT: La sortie devrait être:

Z   Z1  Z2  Z3
Y             
Y1   1   1 NaN
Y2 NaN NaN   1
32
dmi

Voulez-vous dire quelque chose comme ça?

In [39]: df2.pivot_table(values='X', rows='Y', cols='Z', 
                         aggfunc=lambda x: len(x.unique()))
Out[39]: 
Z   Z1  Z2  Z3
Y             
Y1   1   1 NaN
Y2 NaN NaN   1

Notez que l'utilisation de len suppose que vous n'avez pas NAs dans votre DataFrame. Vous pouvez faire x.value_counts().count() ou len(x.dropna().unique()) autrement.

58
Chang She

Je pense que cela sera plus parfait:

df2.pivot_table(values='X',rows=['Y','Z'],cols='X',aggfunc='count')


                 X1 X2
Y   Z       
Y1  Z1   1   1
        Z2   1  NaN
Y2  Z3   1  NaN
19
julian peng

Depuis au moins la version 0.16 de pandas, il ne prend pas le paramètre "lignes"

À partir de 0,23, la solution serait:

df2.pivot_table(values='X', index='Y', columns='Z', aggfunc=pd.Series.nunique)

qui retourne:

Z    Z1   Z2   Z3
Y                
Y1  1.0  1.0  NaN
Y2  NaN  NaN  1.0
11
Javier

aggfunc=pd.Series.nunique fournit un compte distinct.

Nous remercions @hume pour cette solution (voir le commentaire sous la réponse acceptée). Ajout comme réponse ici pour une meilleure découvrabilité.

2
JeeYem

Vous pouvez construire un tableau croisé dynamique pour chaque valeur distincte de X. Dans ce cas, 

for xval, xgroup in g:
    ptable = pd.pivot_table(xgroup, rows='Y', cols='Z', 
        margins=False, aggfunc=numpy.size)

construira un tableau croisé dynamique pour chaque valeur de X. Vous voudrez peut-être indexer ptable à l'aide de xvalue. Avec ce code, je reçois (pour X1)

     X        
Z   Z1  Z2  Z3
Y             
Y1   2   1 NaN
Y2 NaN NaN   1
1
Pablo Navarro