2013-02-21 41 views
11

Supponiamo che io sono un dataframe di creato in questo modo:Girare Pandas dataframe di stringhe in istogramma

import pandas as pd 
s1 = pd.Series(['a', 'b', 'a', 'c', 'a', 'b']) 
s2 = pd.Series(['a', 'f', 'a', 'd', 'a', 'f', 'f']) 
d = pd.DataFrame({'s1': s1, 's2', s2}) 

C'è un bel po 'di scarsità nelle stringhe nei dati reali. Vorrei creare istogrammi dell'occorrenza di stringhe che assomigliano a ciò che viene generato da d.hist() (ad esempio con sottotrami) per s1 e s2 (uno per sottotramma).

Solo facendo d.hist() dà questo errore:

/Library/Python/2.7/site-packages/pandas/tools/plotting.pyc in hist_frame(data, column, by, grid, xlabelsize, xrot, ylabelsize, yrot, ax, sharex, sharey, **kwds) 
    1725   ax.xaxis.set_visible(True) 
    1726   ax.yaxis.set_visible(True) 
-> 1727   ax.hist(data[col].dropna().values, **kwds) 
    1728   ax.set_title(col) 
    1729   ax.grid(grid) 

/Library/Python/2.7/site-packages/matplotlib/axes.pyc in hist(self, x, bins, range, normed, weights, cumulative, bottom, histtype, align, orientation, rwidth, log, color, label, stacked, **kwargs) 
    8099    # this will automatically overwrite bins, 
    8100    # so that each histogram uses the same bins 
-> 8101    m, bins = np.histogram(x[i], bins, weights=w[i], **hist_kwargs) 
    8102    if mlast is None: 
    8103     mlast = np.zeros(len(bins)-1, m.dtype) 

/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/numpy/lib/function_base.pyc in histogram(a, bins, range, normed, weights, density) 
    167    else: 
    168     range = (a.min(), a.max()) 
--> 169   mn, mx = [mi+0.0 for mi in range] 
    170   if mn == mx: 
    171    mn -= 0.5 

TypeError: cannot concatenate 'str' and 'float' objects 

Suppongo che potrei andare manualmente attraverso ogni serie, fare un value_counts(), poi tracciare come un grafico a barre, e creare manualmente le sottotrame. Volevo verificare se esiste un modo più semplice.

risposta

1

Vorrei inserire la serie in un collections.Counter (documentation) (Potrebbe essere necessario prima convertirlo in un elenco). Non sono un esperto di pandas, ma penso che dovresti essere in grado di piegare l'oggetto Counter in un Series, indicizzato dalle stringhe e usarlo per creare i tuoi grafici.

Questo non funziona perché (giustamente) genera errori quando tenta di indovinare dove dovrebbero essere i bordi del raccoglitore, il che non ha senso con le stringhe.

+0

ag, bastonatemi! sì, il contatore è lo strumento per il lavoro! –

+1

Grazie per la risposta. value_counts fa la stessa cosa, ed è una trasformazione Series -> Series (quindi non c'è bisogno di forzarla in una serie). Immagino che mi stavo chiedendo se ci fosse qualche possibilità di fare questo conteggio e tracciare per me automaticamente per questo specifico caso di stringhe, perché ce n'è una per gli interi. – amatsukawa

6

È possibile utilizzare pd.value_counts (value_counts è anche un metodo di serie):

In [20]: d.apply(pd.value_counts) 
Out[20]: 
    s1 s2 
a 3 3 
b 2 NaN 
c 1 NaN 
d NaN 1 
f NaN 3 

e di tracciare il dataframe risultante.

19

ricrea l'dataframe:

import pandas as pd 
s1 = pd.Series(['a', 'b', 'a', 'c', 'a', 'b']) 
s2 = pd.Series(['a', 'f', 'a', 'd', 'a', 'f', 'f']) 
d = pd.DataFrame({'s1': s1, 's2': s2}) 

Per ottenere l'istogramma con sottotrame come desiderato:

d.apply(pd.value_counts).plot(kind='bar', subplots=True) 

enter image description here

Il PO menzionato pd.value_counts in questione. Penso che il pezzo mancante sia solo che non c'è motivo di "manualmente" creare il grafico a barre desiderato.

L'output da d.apply(pd.value_counts) è un dataframe panda. Possiamo tracciare i valori come qualsiasi altro dataframe e selezionare l'opzione subplots=True ci dà quello che vogliamo.