我正在尝试将模拟数据与观测到的降水数据进行直方图匹配。下面显示了一个简单的模拟案例。我得到了模拟和观察数据的CDF并且卡住了。我希望有一条线索可以帮助我克服...提前感谢你
import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import interp1d
import scipy.stats as st
sim = st.gamma(1,loc=0,scale=0.8) # Simulated
obs = st.gamma(2,loc=0,scale=0.7) # Observed
x = np.linspace(0,4,1000)
simpdf = sim.pdf(x)
obspdf = obs.pdf(x)
plt.plot(x,simpdf,label='Simulated')
plt.plot(x,obspdf,'r--',label='Observed')
plt.title('PDF of Observed and Simulated Precipitation')
plt.legend(loc='best')
plt.show()
plt.figure(1)
simcdf = sim.cdf(x)
obscdf = obs.cdf(x)
plt.plot(x,simcdf,label='Simulated')
plt.plot(x,obscdf,'r--',label='Observed')
plt.title('CDF of Observed and Simulated Precipitation')
plt.legend(loc='best')
plt.show()
# Inverse CDF
invcdf = interp1d(obscdf,x)
transfer_func = invcdf(simcdf)
plt.figure(2)
plt.plot(transfer_func,x,'g-')
plt.show()
答案 0 :(得分:4)
我尝试重现您的代码,并收到以下错误:
ValueError: A value in x_new is above the interpolation range.
如果你看一下你的两张CDF的情节,可以很清楚地知道发生了什么:
现在定义invcdf = interp1d(obscdf, x)
时,请注意obscdf
的范围是
>>> obscdf[0]
0.0
>>> obscdf[-1]
0.977852889924409
所以invcdf
只能在这些限制之间插入值:除了它们之外,我们必须进行外推,这不是完全定义的。 SciPy的默认行为是在被要求推断时引发错误。这正是您要求invcdf(simcdf)
时会发生什么,因为
>>> simcdf[-1]
0.99326205300091452
超出了插值范围。
如果您阅读the interp1d
docs,您会看到可以修改此行为
invcdf = interp1d(obscdf, x, bounds_error=False)
现在一切正常,但你需要将你的绘图参数的顺序颠倒到plt.plot(x, transfer_func,'g-')
以获得与你发布的图中相同的内容: