概率密度函数来自python中的直方图以适应另一个histrogram

mad*_*one 7 python numpy matplotlib scipy

我有一个关于拟合和获取随机数的问题.

情况是这样的:

首先,我有一个数据点的直方图.我想把这个直方图解释为概率密度函数(例如2个自由参数),这样我就可以用它来产生随机数.我也想用这个函数来拟合另一个直方图.

Ale*_*x I 7

您可以使用累积密度函数从任意分布生成随机数,如此处所述.

使用直方图产生平滑的累积密度函数并非完全无关紧要; 你可以使用插值例如scipy.interpolate.interp1d()来表示你的箱子中心之间的值,这对于具有相当大数量的箱子和物品的直方图是可行的.但是,您必须决定概率函数的尾部形式,即对于小于最小bin或大于最大bin的值.你可以给你的分布高斯尾巴,例如根据你的直方图拟合高斯),或者适合你的问题的任何其他形式的尾巴,或者简单地截断分布.

例:

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()
Run Code Online (Sandbox Code Playgroud)

这不会处理尾部,它可以更好地处理bin边缘,但它会让你开始使用直方图来生成具有相同分布的更多值.

PS您还可以尝试拟合由几个值描述的特定已知分布(我认为这是您在问题中提到的),但上述非参数方法更通用.

  • 这是我的最终版本,它运作顺利,再次感谢.`bins = np.linspace(0,.5,num = 800)counts18,bins = np.histogram(Z_DATA [InData18],bins = bins)x = np.cumsum(counts18)*1./np.sum(counts18 )*1.y = bins [range(len(x)+1)] y = y [1:] fit = scipy.interpolate.interp1d(x,y)plt.hist(fit(np.random.uniform(x [0], x [-1],len(data))),bins = y)plt.hist(data,alpha = 0.3,bins = y)plt.show()` (2认同)