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

问题描述 投票:0回答:4

我们可以使用

创建 ECDF
import numpy as np
from statsmodels.distributions.empirical_distribution import ECDF
ecdf = ECDF([3, 3, 1, 4])

然后在

点获得 ECDF
ecdf(x)

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

http://www.statsmodels.org/stable/generated/statsmodels.distributions.empirical_distribution.ECDF.html?highlight=ecdf
来看,好像没有实施。

有什么办法可以做到这一点吗?或者还有其他库吗?

python numpy statsmodels
4个回答
12
投票

由于经验 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)]

产生:

10

由于我们记得对于离散分布(如经验 cdf),分位数函数被定义为 here ,我们意识到我们必须取第 0.975n 个(向上舍入)最大值。


8
投票

这是我的建议。线性插值,因为 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))

它产生以下输出,

97.5 percentile: 6.75

还有这张图。


6
投票

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

同样,Series/DataFrame 也有

pandas.quantile(q=0.97)


0
投票

它插值是正确的,但插值是在您正在使用的 x 周围的 2 个点之间,而不是 x 的最小值和最大值。

来自 Numpy 文档

可选的

method
参数指定当 所需的分位数位于两个索引
i
j = i + 1
之间。

来自 Pandas 文档

插值:{'线性','较低','较高','中点','最近'} 此可选参数指定要使用的插值方法, 当所需的分位数位于两个数据点

i
j
之间时:

        * linear: `i + (j - i) * fraction`, where `fraction` is the
© www.soinside.com 2019 - 2024. All rights reserved.