web-dev-qa-db-fra.com

Comment créer un histogramme à partir d'une liste de chaînes en Python?

J'ai une liste de chaînes:

a = ['a', 'a', 'a', 'a', 'b', 'b', 'c', 'c', 'c', 'd', 'e', 'e', 'e', 'e', 'e']

Je veux faire un histogramme pour afficher la distribution de fréquence des lettres. Je peux faire une liste contenant le nombre de chaque lettre en utilisant les codes suivants:

from itertools import groupby
b = [len(list(group)) for key, group in groupby(a)]

Comment est-ce que je fais l'histogramme? J'ai peut-être un million d'éléments de cette liste a.

18
Gray

Très facile avec Pandas.

import pandas
from collections import Counter
a = ['a', 'a', 'a', 'a', 'b', 'b', 'c', 'c', 'c', 'd', 'e', 'e', 'e', 'e', 'e']
letter_counts = Counter(a)
df = pandas.DataFrame.from_dict(letter_counts, orient='index')
df.plot(kind='bar')

Notez que Counter effectue un compte de fréquence, notre type de tracé est donc 'bar' et non 'hist'.

histogram of letter counts

30
notconfusing

Comme @notconfusing l'a souligné ci-dessus, cela peut être résolu avec Pandas et Counter. Si, pour pour une raison quelconque, vous n’avez pas besoin d’utiliser Pandas, vous ne pourrez vous en sortir qu’avec matplotlib en utilisant la fonction du code suivant:

from collections import Counter
import numpy as np
import matplotlib.pyplot as plt

a = ['a', 'a', 'a', 'a', 'b', 'b', 'c', 'c', 'c', 'd', 'e', 'e', 'e', 'e', 'e']
letter_counts = Counter(a)

def plot_bar_from_counter(counter, ax=None):
    """"
    This function creates a bar plot from a counter.

    :param counter: This is a counter object, a dictionary with the item as the key
     and the frequency as the value
    :param ax: an axis of matplotlib
    :return: the axis wit the object in it
    """

    if ax is None:
        fig = plt.figure()
        ax = fig.add_subplot(111)

    frequencies = counter.values()
    names = counter.keys()

    x_coordinates = np.arange(len(counter))
    ax.bar(x_coordinates, frequencies, align='center')

    ax.xaxis.set_major_locator(plt.FixedLocator(x_coordinates))
    ax.xaxis.set_major_formatter(plt.FixedFormatter(names))

    return ax

plot_bar_from_counter(letter_counts)
plt.show()

Qui produira  enter image description here

8
Ramon Martinez

Plutôt que d'utiliser groupby() (ce qui nécessite de trier vos entrées), utilisez collections.Counter() ; il n'est pas nécessaire de créer des listes intermédiaires uniquement pour compter les entrées:

from collections import Counter

counts = Counter(a)

Vous n'avez pas vraiment précisé ce que vous considérez être un "histogramme". Supposons que vous souhaitiez le faire sur le terminal:

width = 120  # Adjust to desired width
longest_key = max(len(key) for key in counts)
graph_width = width - longest_key - 2
widest = counts.most_common(1)[0][1]
scale = graph_width / float(widest)

for key, size in sorted(counts.items()):
    print('{}: {}'.format(key, int(size * scale) * '*'))

Démo:

>>> from collections import Counter
>>> a = ['a', 'a', 'a', 'a', 'b', 'b', 'c', 'c', 'c', 'd', 'e', 'e', 'e', 'e', 'e']
>>> counts = Counter(a)
>>> width = 120  # Adjust to desired width
>>> longest_key = max(len(key) for key in counts)
>>> graph_width = width - longest_key - 2
>>> widest = counts.most_common(1)[0][1]
>>> scale = graph_width / float(widest)
>>> for key, size in sorted(counts.items()):
...     print('{}: {}'.format(key, int(size * scale) * '*'))
... 
a: *********************************************************************************************
b: **********************************************
c: **********************************************************************
d: ***********************
e: *********************************************************************************************************************

Des outils plus sophistiqués se trouvent dans les fonctions numpy.histogram() et matplotlib.pyplot.hist() . Ceux-ci font le décompte pour vous, avec matplotlib.pyplot.hist() vous fournissant également une sortie graphique.

5
Martijn Pieters

voici une approche concise tout-pandas:

a = ['a', 'a', 'a', 'a', 'b', 'b', 'c', 'c', 'c', 'd', 'e', 'e', 'e', 'e', 'e']
pd.Series(a).value_counts().plot('bar')

 barplot of counts

4
drammock

Découvrez matplotlib.pyplot.bar. Il existe également numpy.histogram qui est plus flexible si vous souhaitez des bacs plus larges.

1
tommyo

Un moyen simple et efficace de créer un histogramme de caractère en python

import numpy as np

import matplotlib.pyplot as plt

from collections import Counter



a = []
count =0
d = dict()
filename = raw_input("Enter file name: ")
with open(filename,'r') as f:
    for Word in f:
        for letter  in Word:
            if letter not in d:
                d[letter] = 1
            else:
                d[letter] +=1
num = Counter(d)
x = list(num.values())
y = list(num.keys())

x_coordinates = np.arange(len(num.keys()))
plt.bar(x_coordinates,x)
plt.xticks(x_coordinates,y)
plt.show()
print x,y

0
Mitul Panchal