2017-06-30 1 views
0

J'ai des données sur la présence d'un ensemble de métabolites dans divers compartiments d'un système. J'ai aussi des informations sur le type de chacun des métabolites. Je veux un tableau de fréquence montrant le nombre de métabolites de chaque type dans chaque compartiment. Le look de données quelque chose comme ceci:Tableau des fréquences des pandas basé sur plusieurs tableaux croisés

df = pd.DataFrame({'met_id':['met_a','met_b','met_c','met_d','met_e','met_f'], 
        'met_type':['amino_acid','amino_acid','lipid','lipid','peptide','peptide'], 
        'comp_1':[True,False,True,True,False,True], 
        'comp_2':[False,True,True,False,True,True]}) 
print df 

donne

comp_1 comp_2 met_id met_type 
0 True False met_a amino_acid 
1 False True met_b amino_acid 
2 True True met_c  lipid 
3 True False met_d  lipid 
4 False True met_e  peptide 
5 True True met_f  peptide 

Je veux un tableau récapitulatif (ou dataframe) comme ceci:

met_type  comp_1 comp_2 
amino_acid 1  1 
lipid   2  1 
peptide  1  2 

indiquant combien de chaque type de métabolite est dans chaque compartiment. Je peux obtenir les comptes en utilisant un tableau croisé ainsi:

pd.crosstab(df_test.met_type,df_test.comp_1)[True] 

donne

met_type 
amino_acid 1 
lipid   2 
peptide  1 
Name: True, dtype: int64 

et je pense que je peux concaténer chacune de ces séries, mais est-il une belle façon de créer une table avec des comptes pour tous les colonnes du compartiment?

Répondre

1

Vous pouvez utiliser groupby signifie

df = pd.DataFrame({'met_id': 
['met_a','met_b','met_c','met_d','met_e','met_f'], 
       'met_type': 
['amino_acid','amino_acid','lipid','lipid','peptide','peptide'], 
        'comp_1':[True,False,True,True,False,True], 
        'comp_2':[False,True,True,False,True,True]}) 
dfn = df.groupby("met_type").mean() 
dfn = dfn[['comp_1','comp_2']]*2 

Cela vous donnera le tableau récapitulatif

 
      comp_1 comp_2 
met_type     
amino_acid  1.0  1.0 
lipid   2.0  1.0 
peptide  1.0  2.0 

Comme vous le suggérez, nous pouvons utiliser la somme (était encore un débutant ce moment :))

dfn = df.groupby("met_type")['comp_1','comp_2'].sum().astype(int) 
 
      comp_1 comp_2 
met_type     
amino_acid  1  1 
lipid   2  1 
peptide   1  2 
+0

Ah, cela fonctionne sur m y exemple de jouet, mais dans mon jeu de données réel 'comp_1' et 'comp_2' sont de type booléen donc j'obtiens une erreur 'DataError: Aucun type numérique à agréger'. Je vais modifier ma question pour clarifier cela - y a-t-il une approche similaire pour les booléens? –

+0

Pouvez-vous montrer le jeu de données réel – Dark

+1

Désolé, en fait je pense que le problème est qu'il ya des NaN dans les listes booléennes qui cassent votre réponse. Je peux juste remplacer les NaN par Falses pour les besoins du résumé et ça marche super! Je vais accepter votre réponse et convertir les NaN. –