2017-08-03 3 views
3

J'ai une trame de données avec 2 variables: ID et outcome. J'essaye de groupbyID d'abord, et compte le nombre de valeurs uniques de outcome dans ce ID.Grouper et compter le nombre de valeurs uniques (Pandas)

df 
ID outcome 
1  yes 
1  yes 
1  yes 
2  no 
2  yes 
2  no 

Sortie prévue:

ID yes no 
1  3  0 
2  1  2 

Mon code df[['PID', 'outcome']].groupby('PID')['outcome'].nunique() donne le numéro de la valeur unique lui-même, tel que:

ID 
1 2 
2 2 

Mais je besoin des chefs d'yes et no, comment puis-je y parvenir? Merci!

Répondre

5

Que diriez-vous de pd.crosstab?

In [1217]: pd.crosstab(df.ID, df.outcome) 
Out[1217]: 
outcome no yes 
ID    
1   0 3 
2   2 1 
+1

Je dois trouver un nouveau ** Option 2 ** – piRSquared

+0

@piRSquared Ce n'était qu'une question de temps avant que quelqu'un d'autre ne comprenne que c'était possible: p –

+0

Et pourquoi pas? C'est bien! – Kay

1

Groupez sur la colonne ID puis agrégation en utilisant value_counts sur la colonne outcome. Cela entraînerait une série, vous devez donc le convertir en une image de données en utilisant .to_frame() afin que vous puissiez dépiler le oui/non (c'est-à-dire les avoir comme colonnes). Remplissez ensuite les valeurs nulles avec zéro.

df_total = df.groupby('ID')['outcome'].value_counts().to_frame().unstack(fill_value=0) 
df_total.columns = df_total.columns.droplevel() 
>>> df_total 
outcome no yes 
ID    
1   0 3 
2   2 1 
+0

@piRSquared Oui. Merci. – Alexander

0

Utilisez set_index et pd.concat

df1 = df.set_index('ID') 
pd.concat([df1.outcome.eq('yes').sum(level=0), 
      df1.outcome.ne('yes').sum(level=0)], keys=['yes','no'],axis=1).reset_index() 

Sortie:

ID yes no 
0 1 3.0 0.0 
1 2 1.0 2.0 
0

la configuration la plus efficace, qui empêchera tout passé, les bugs actuels et futurs et tirer parti des fonctions FAST vectorisés est faire la chose (follement simple) suivante:

df['dummy_yes'] = df.outcome == 'yes' 
df['dummy_no'] = df.outcome == 'no' 

df.groupby('ID').sum() 
+0

Pourquoi pensez-vous que les autres solutions causeront des bugs passés, présents ou futurs? –

+0

c'est quelque chose qui fonctionne dans n'importe quelle langue.J'ai eu quelques bugs sévères et subtils dans le passé quand j'essayais de faire plus de trucs pandonic –

+0

@coldspeed voici c'est https://stackoverflow.com/questions/36337012/how-to-get-multiple-conditional-operations-after-a -pandas-groupby –

4

Option 2
pd.factorize + np.bincount
Ceci est alambiquée et douloureux ... mais très rapide.

fi, ui = pd.factorize(df.ID.values) 
fo, uo = pd.factorize(df.outcome.values) 

n, m = ui.size, uo.size 
pd.DataFrame(
    np.bincount(fi * m + fo, minlength=n * m).reshape(n, m), 
    pd.Index(ui, name='ID'), pd.Index(uo, name='outcome') 
) 

outcome yes no 
ID    
1   3 0 
2   1 2 

Option C

pd.get_dummies(d.ID).T.dot(pd.get_dummies(d.outcome)) 

    no yes 
1 0 3 
2 2 1 

Option IV.

df.groupby(['ID', 'outcome']).size().unstack(fill_value=0) 
+0

merci! Que signifie «T» dans votre option C? – Kay

+0

cela signifie "Terrible" hahaha –

+1

@Kay transposer de la dataframe – piRSquared