2015-04-27 15 views
5

In breve, qual è la mia migliore opzione per un grafico di tipo di distribuzione (istogramma o kde) quando i miei dati sono ponderati?Grafici di tipo distribuzione (istogramma/kde) con dati ponderati

df = pd.DataFrame({ 'x':[1,2,3,4], 'wt':[7,5,3,1] }) 

df.x.plot(kind='hist',weights=df.wt.values) 

Questo funziona bene, ma Seaborn non accetterà una kwarg pesi, vale a dire

sns.distplot(df.x, bins=4,    # doesn't work like this 
       weights=df.wt.values)  # or with kde=False added 

Sarebbe anche bello se kde accetterebbero pesi Ma né i panda né Seaborn sembra permetterlo.

Mi rendo conto che i dati potrebbero essere espansi per simulare la ponderazione e che è facile qui ma non di molto uso con i miei dati reali con pesi in centinaia o migliaia, quindi non sto cercando una soluzione del genere.

In ogni caso, questo è tutto. Sto solo cercando di scoprire cosa (se non altro) posso fare con i dati ponderati oltre all'istogramma di base dei panda. Non ho ancora ingannato con bokeh, ma sono anche i suggerimenti bokeh.

risposta

4

Devi capire che Seaborn utilizza le funzioni di plottaggio molto matplotlib che anche i panda usano.

quanto documentation stati, sns.distplot non accetta un argomento weights, tuttavia ci vuole un argomento hist_kws, che sarà inviato alla chiamata sottostante plt.hist. Così, questo dovrebbe fare quello che vuoi:

sns.distplot(df.x, bins=4, hist_kws={'weights':df.wt.values}) 
+0

Sì, grazie, che è utile. Non ero sicuro di come passare il kwarg a matplotlib. Ora avrò una votazione in anticipo, ma lascerò aperto un po 'più a lungo nel caso qualcuno abbia idee su kde o simili. – JohnE

+1

Seaborns kde plots usa i modelli statici del pacchetto python per i calcoli. Le funzioni rilevanti prendono un argomento di pesi, ma sembra che questo non venga inoltrato da Seaborn. I file sorgente rilevanti: https://github.com/mwaskom/seaborn/blob/master/seaborn/distributions.py e https://github.com/statsmodels/statsmodels/blob/master/statsmodels/nonparametric/kde.py – hitzg

+0

OK, grazie. Sembra che i pesi non siano ancora stati implementati (non posso dirlo con certezza da una rapida scrematura). Ad ogni modo, lo chiudo ora e forse faccio una domanda più incentrata su kde in un secondo momento. – JohnE

0

ho risolto questo problema con il ricampionamento i punti di dati in base al loro peso.

È possibile farlo in questo modo:

`

from random import random 
from bisect import bisect 

def weighted_choice(choices): 
    values, weights = zip(*choices) 
    total = 0 
    cum_weights = [] 
    for w in weights: 
     total += w 
     cum_weights.append(total) 
    x = random() * total 
    i = bisect(cum_weights, x) 
    return values[i] 

samples = [([5, 0.5], 0.1), ([0, 10], 0.3), ([0, -4], 0.3)] 
choices = np.array([weighted_choice(samples) for c in range(1000)]) 
sns.distributions.kdeplot(choices[:, 0], choices[:, 1], shade=True) 

` enter image description here

Problemi correlati