Python:逆经验累积分布函数(ECDF)?

cqc*_*991 5 python numpy statsmodels

我们可以创建ECDF

import numpy as np
from statsmodels.distributions.empirical_distribution import ECDF
ecdf = ECDF([3, 3, 1, 4])
Run Code Online (Sandbox Code Playgroud)

然后获得当时的ECDF

ecdf(x)
Run Code Online (Sandbox Code Playgroud)

但是,如果我想知道x为百分位数97.5%怎么办?

http://www.statsmodels.org/stable/generated/statsmodels.distributions.empirical_distribution.ECDF.html?highlight=ecdf,似乎没有实施.

有没有办法做到这一点?还是其他任何图书馆?

Ben*_*hty 8

由于经验CDF只是在每个数据点放置1/n的质量,因此第97.5分位数只是大于所有其他点的97.5%的数据点.要查找此值,您只需按升序对数据进行排序,然后找到0.975n的最大值.

sample = [1, 5, 2, 10, -19, 4, 7, 2, 0, -1]
n = len(sample)
sort = sorted(sample)
print sort[int(n * 0.975)]
Run Code Online (Sandbox Code Playgroud)

哪个产生:

10
Run Code Online (Sandbox Code Playgroud)

由于我们记得比离散分布(如经验cdf),分位数函数在这里定义(抱歉,不能嵌入图像,因为这是我的第一篇文章),我们意识到我们必须采取0.975n-th(四舍五入)最大的价值.

希望这可以帮助!

编辑(1/16/18)易读性.


Bil*_*ell 5

这是我的建议。线性插值,因为无论如何只能从相当大的样本中有效地估计 dfs。可以获得内插线段,因为它们的端点出现在样本中的不同值处。

import statsmodels.distributions.empirical_distribution as edf
from scipy.interpolate import interp1d
import numpy as np
import matplotlib.pyplot as plt

sample = [1,4,2,6,5,5,3,3,5,7]
sample_edf = edf.ECDF(sample)

slope_changes = sorted(set(sample))

sample_edf_values_at_slope_changes = [ sample_edf(item) for item in slope_changes]
inverted_edf = interp1d(sample_edf_values_at_slope_changes, slope_changes)

x = np.linspace(0.1, 1)
y = inverted_edf(x)
plt.plot(x, y, 'ro', x, y, 'b-')
plt.show()

print ('97.5 percentile:', inverted_edf(0.975))
Run Code Online (Sandbox Code Playgroud)

它产生以下输出,

97.5 percentile: 6.75
Run Code Online (Sandbox Code Playgroud)

和这个图。 倒置经验CDF


小智 5

numpy.quantile(x, q=.975) 将返回沿数组 x 的值,其中 ecdf 为 0.975。

同样,还有pandas.quantile(q=0.97)系列/数据帧。

  • 这里必须小心,因为 numpy 百分位数和分位数函数仅对 x 的最小值和最大值之间的间隔进行插值(默认为线性),因此它与经验 cdf 的倒数不同。 (3认同)