Pandas Python: tableau croisé dynamique avec aggfunc = count 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 (dernier appel le plus récent): ... AttributeError: objet' Index' n'a pas d'attribut 'index'

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

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


EDIT: la sortie doit être:

Z   Z1  Z2  Z3
Y             
Y1   1   1 NaN
Y2 NaN NaN   1
30
demandé sur dmi 2012-10-12 17:43:47

5 réponses

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()) sinon.

54
répondu Chang She 2014-02-17 16:29:03

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
14
répondu julian peng 2013-10-28 08:48:01

Depuis au moins la version 0.16 des 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 renvoie:

Z    Z1   Z2   Z3
Y                
Y1  1.0  1.0  NaN
Y2  NaN  NaN  1.0
5
répondu Javier 2018-07-16 17:45:37

, 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)

Construire un tableau croisé dynamique pour chaque valeur de X. Vous pouvez indexer ptable en utilisant le xvalue. Avec ce code, je reçois (pour X1)

     X        
Z   Z1  Z2  Z3
Y             
Y1   2   1 NaN
Y2 NaN NaN   1
1
répondu Pablo Navarro 2012-10-12 15:21:39

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

Crédit à @hume pour cette solution (voir commentaire sous la réponse acceptée). Ajouter comme réponse ici pour une meilleure découvrabilité.

0
répondu JeeYem 2018-07-06 03:06:31