2017-08-31 7 views
0

J'ai une base de données pandas avec 4 colonnes et quelques milliers de lignes. Toutes les entrées sont vraies ou fausses. Appelons l'espace de données 'df' et les colonnes 'c0', 'c1', 'c2' et 'c3'. Je suis intéressé par le nombre de lignes ont chacune des 2^4 = 16 valeurs possibles de vérité, alors je me fais un tableau croisé:Création d'un graphique à bulles à partir d'un tableau croisé de pandas

xt = pd.crosstab([df.c0,df.c1],[df.c2,df.c3]) 
print(xt) 

qui affiche une belle table 4x4 de cellules, chaque cellule contenant le nombre de lignes qui ont cette combinaison de valeurs de vérité. Mieux encore, la disposition spatiale de ces 16 cellules est significative et utile pour moi. OK, tout va bien. Mais comment puis-je le tracer?

Plus précisément, je voudrais faire un graphique à bulles de ces chefs d'accusation de tableau croisé, -à-dire une représentation graphique des données de tableau croisé dans le même arrangement spatial comme cela a été montré dans le tableau, mais maintenant remplacer chaque numéro avec une couleur blob (disons un cercle) de surface proportionnelle au nombre. Donc, c'est un nuage de points avec les quatre valeurs de vérité (c0, c1) le long d'un axe, les quatre valeurs de vérité (c2, c3) le long de l'autre axe, et une grille régulière 4x4 de cercles de différentes tailles. Je sais que je peux faire un graphique à bulles en passant des données de taille au mot-clé 's' de la fonction de dispersion de matplotlib, mais je ne peux pas trouver un moyen simple de dire aux pandas de créer un nuage de points en tant que coordonnées x, en-têtes de ligne en coordonnées y et valeurs de données en tant que tailles de bulles pour un diagramme de dispersion. J'ai eu de la chance en convertissant mon dataframe en un tableau chiffré et en traçant cela, mais ensuite je perds la structure des étiquettes d'axes du tableau croisé. (Oui, je pourrais juste reconstruire les étiquettes de tique à la main, mais je voudrais pouvoir reproduire cette tâche algorithmiquement pour d'autres ensembles de données semblables.)

EDIT: Inspiré par la réponse de @piRSquared ci-dessous, voici quelques clarification de ce que je demande. Ce code se rapproche de ce que je veux, mais les axes du graphique résultant ont perdu toute information sur la structure de l'étiquette MultiIndex en couches de l'objet tableau croisé.

import pandas as pd 
import numpy as np 

randomData=np.random.choice([True,False],size=(100, 4),p=[.6,.4]) 
df = pd.DataFrame(randomData, columns=['c0','c1','c2','c3']) 
xt=pd.crosstab([df.c0,df.c1], [df.c2,df.c3]) 

x=np.array([range(4)]*4) 
y=x.transpose()[::-1,:] 
pl.scatter(x,y,s=np.array(xt)*10) 

(lien pour tracer l'image, puisque je n'ai pas assez réputation pour intégrer:. a scatter plot with poorly labelled axes) Idéalement, les axes des étiquettes auraient une structure visuelle stabilisée dérivée de sous-jacente multiindice de l'objet tableau croisé, un peu comme cela :

c2   False  True  
c3   False True False True 
c0 c1       
False False  0  8  4  9 
     True  3  2  4 10 
True False  7  5  3 10 
     True  2  7  8 18 

Ou, peut-être, quelque chose qui rappelle ce que la légende et l'axe x expriment ici:

xt.plot(kind='bar',stacked=True) 

(Une autre parcelle lien image: a stack plot that knows about the multiindex nature of its underlying dataframe.)

Répondre

1

Hope this helps

df = pd.DataFrame(
    np.random.choice(
     np.arange(6), 
     size=(100, 2), 
     p=np.arange(1, 7)/21 
    ), columns=list('AB') 
) 

c = pd.crosstab(df.A, df.B).stack().reset_index(name='C') 

c.plot.scatter('A', 'B', s=c.C * 10) 

enter image description here

+0

Cela se rapproche de faire le travail (et est très intelligent!), Mais le tableau croisé dans le problème Orignal est multiindexed, et il est pas évident pour moi comment extrapoler cette réponse à l'affaire multiIndex. –

+0

Ce n'est pas évident pour moi de savoir à quoi vous voulez ressembler. Pouvez-vous dessiner, prendre une photo et l'afficher. – piRSquared

+0

Ok, je vais éditer mon post pour clarifier ce que je demande. –