我正在尝试将模拟数据与观测到的降水数据进行直方图匹配。下面显示了一个简单的模拟案例。我得到了模拟和观察数据的 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()

最佳答案

我试图重现您的代码,但出现以下错误:

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-') 以获得与您发布的图中相同的顺序:

关于python - Python中的直方图匹配,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14160806/

10-12 16:50