web-dev-qa-db-fra.com

Pandas histogramme df.hist () groupé par

Comment tracer un histogramme avec pandas DataFrame.hist () en utilisant group by? J'ai un bloc de données avec 5 colonnes: "A", "B", "C", "D" et "Groupe"

Il existe deux classes de groupes: "oui" et "non"

En utilisant:

df.hist() 

J'obtiens l'hist pour chacune des 4 colonnes.

enter image description here

Maintenant, je voudrais obtenir les mêmes 4 graphiques mais avec des barres bleues (groupe = "oui") et des barres rouges (groupe = "non").

J'ai essayé sans succès:

df.hist(by = "group")

pandas hist went wrong

14
Hangon

Ce n'est pas la solution de contournement la plus flexible mais fonctionnera spécifiquement pour votre question.

def sephist(col):
    yes = df[df['group'] == 'yes'][col]
    no = df[df['group'] == 'no'][col]
    return yes, no

for num, alpha in enumerate('abcd'):
    plt.subplot(2, 2, num)
    plt.hist(sephist(alpha)[0], bins=25, alpha=0.5, label='yes', color='b')
    plt.hist(sephist(alpha)[1], bins=25, alpha=0.5, label='no', color='r')
    plt.legend(loc='upper right')
    plt.title(alpha)
plt.tight_layout(pad=0.4, w_pad=0.5, h_pad=1.0)

enter image description here

Vous pouvez rendre cela plus générique en:

  • ajout d'un paramètre df et by à sephist: def sephist(df, by, col)
  • rendre la boucle des sous-parcelles plus flexible: for num, alpha in enumerate(df.columns)

Parce que le premier argument de matplotlib.pyplot.hist peut prendre

soit un seul tableau ou une séquence de tableaux qui ne doivent pas nécessairement être de la même longueur

... une alternative serait:

for num, alpha in enumerate('abcd'):
    plt.subplot(2, 2, num)
    plt.hist((sephist(alpha)[0], sephist(alpha)[1]), bins=25, alpha=0.5, label=['yes', 'no'], color=['r', 'b'])
    plt.legend(loc='upper right')
    plt.title(alpha)
plt.tight_layout(pad=0.4, w_pad=0.5, h_pad=1.0)

enter image description here

10
Brad Solomon

Utiliser Seaborn

Si vous êtes prêt à utiliser Seaborn, un tracé avec plusieurs sous-tracés et plusieurs variables dans chaque sous-tracé peut facilement être créé à l'aide de seaborn.FacetGrid.

import numpy as np; np.random.seed(1)
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

df = pd.DataFrame(np.random.randn(300,4), columns=list("ABCD"))
df["group"] = np.random.choice(["yes", "no"], p=[0.32,0.68],size=300)

df2 = pd.melt(df, id_vars='group', value_vars=list("ABCD"), value_name='value')

bins=np.linspace(df2.value.min(), df2.value.max(), 10)
g = sns.FacetGrid(df2, col="variable", hue="group", palette="Set1", col_wrap=2)
g.map(plt.hist, 'value', bins=bins, ec="k")

g.axes[-1].legend()
plt.show()

enter image description here

12