2012-11-20 10 views
7

Ho una domanda riguardante il montaggio e ottenere numeri casuali.funzione di densità di probabilità dall'istogramma in python per adattarsi a un altro istogramma

situazione è come tale:

Innanzitutto ho un istogramma di punti di dati. Vorrei interpretare questo istogramma come funzione di densità di probabilità (con ad esempio 2 parametri liberi) in modo che io possa usarlo per produrre numeri casuali E vorrei anche usare quella funzione per adattare un altro istogramma.

+7

forse questo questo dovrebbe essere riaperto e migliorato –

+2

Se non capisci la domanda, non è sicuro che questa non sia una domanda, solo perché non lo hai fatto. Cerca di capire prima. Mi unisco a Saullo. – Geeocode

risposta

4

È possibile utilizzare una funzione di densità cumulativa per generare numeri casuali da una distribuzione arbitraria, come described here.

L'utilizzo di un istogramma per produrre una funzione di densità cumulativa uniforme non è del tutto banale; è possibile utilizzare l'interpolazione, ad esempio scipy.interpolate.interp1d() per i valori compresi tra i centri degli scomparti e che funzioneranno correttamente per un istogramma con un numero ragionevolmente elevato di contenitori e articoli. Tuttavia, è necessario decidere la forma delle code della funzione di probabilità, ovvero per valori inferiori al contenitore più piccolo o maggiore rispetto al contenitore più grande. Puoi dare la tua distribuzione di code gaussiane basandoti ad esempio su un gaussiano per il tuo istogramma), o su qualsiasi altra forma di coda appropriata al tuo problema, o semplicemente troncare la distribuzione.

Esempio:

import numpy 
import scipy.interpolate 
import random 
import matplotlib.pyplot as pyplot 

# create some normally distributed values and make a histogram 
a = numpy.random.normal(size=10000) 
counts, bins = numpy.histogram(a, bins=100, density=True) 
cum_counts = numpy.cumsum(counts) 
bin_widths = (bins[1:] - bins[:-1]) 

# generate more values with same distribution 
x = cum_counts*bin_widths 
y = bins[1:] 
inverse_density_function = scipy.interpolate.interp1d(x, y) 
b = numpy.zeros(10000) 
for i in range(len(b)): 
    u = random.uniform(x[0], x[-1]) 
    b[i] = inverse_density_function(u) 

# plot both   
pyplot.hist(a, 100) 
pyplot.hist(b, 100) 
pyplot.show() 

Questo non gestisce le code, ed è in grado di gestire bin bordi meglio, ma sarebbe iniziare a utilizzare un istogramma per generare più valori con la stessa distribuzione.

P.S. Potresti anche provare ad adattare una specifica distribuzione nota descritta da alcuni valori (che penso sia quello che hai menzionato nella domanda) ma l'approccio non parametrico di cui sopra è più generico.

+0

, grazie per la rapida risposta, anche l'interpolazione era nella mia mente, ma come hai detto in primo luogo non può prendersi cura dei valori anomali e anche che non è realmente una funzione di densità ma più una copia dell'istogramma iniziale. – madzone

+2

questa è la mia versione finale, funziona senza problemi, grazie ancora. 'bin = np.linspace (0, .5, num = 800) conteggi18, bin = np.histogram (Z_DATA [InData18], bin = bins) x = np.cumsum (conteggi18) * 1./np. sum (counts18) * 1. y = bidoni [intervallo (len (x) +1)] y = y [1:] fit = scipy.interpolate.interp1d (x, y) plt.hist (adattamento (np.random.uniform (x [0], x [-1], len (dati))), bin = y) plt.hist (dati, alfa = 0,3, bin = y) plt.show() ' – madzone

Problemi correlati