首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >计算错误的np.quantile?

计算错误的np.quantile?
EN

Stack Overflow用户
提问于 2019-04-04 22:16:12
回答 2查看 803关注 0票数 2

在某些设置下,np.quantile在确定正确的分位数时会出错。这是一个bug吗?

代码语言:javascript
复制
x = np.array([374, 358, 341, 355, 342, 334, 353, 346, 355, 344,
              349, 330, 352, 328, 336, 359, 361, 345, 324, 386,
              334, 370, 349, 327, 342, 354, 361, 354, 377, 324])

q = np.quantile(x, 0.25)

print(q)

print(len(x[x<=q]) / len(x))

print(len(x[x>=q]) / len(x))

输出:

代码语言:javascript
复制
337.25

0.26666666666666666

0.7333333333333333

0.73意味着只有73%的值大于或等于确定的分位数;根据定义,它应该是>= 75%

EN

回答 2

Stack Overflow用户

发布于 2019-04-04 23:11:38

https://github.com/numpy/numpy/blob/v1.15.1/numpy/lib/function_base.py#L3543-L3644

代码语言:javascript
复制
default value is linear
    interpolation : {'linear', 'lower', 'higher', 'midpoint', 'nearest'}
        This optional parameter specifies the interpolation method to
        use when the desired quantile lies between two data points
        ``i < j``:
            * linear: ``i + (j - i) * fraction``, where ``fraction``
              is the fractional part of the index surrounded by ``i``
              and ``j``.
            * lower: ``i``.
            * higher: ``j``.
            * nearest: ``i`` or ``j``, whichever is nearest.
            * midpoint: ``(i + j) / 2``.

如果你选择“更高”,你就会得到你想要的。

票数 1
EN

Stack Overflow用户

发布于 2019-04-04 23:26:00

正如@SamProell所说,有不同的计算百分位数的约定,你可以看到here with quartile's computing methods (美国方式)。这里我们有一个偶数的数据,所以让我们坚持第一种方法,让我们试着看看我们将如何“手动”完成它。

首先,对数据进行排序:

代码语言:javascript
复制
> x2=np.sort(x)
> print(x2)
array([324, 324, 327, 328, 330, 334, 334, 336, 341, 342, 342, 344, 345,
       346, 349, 349, 352, 353, 354, 354, 355, 355, 358, 359, 361, 361,
       370, 374, 377, 386])

然后将数据一分为二:

代码语言:javascript
复制
> x2_low = x2[:int(len(x2)/2)]
array([324, 324, 327, 328, 330, 334, 334, 336, 341, 342, 342, 344, 345,
       346, 349])
> x2_up = x2[int(len(x2)/2):]
array([349, 352, 353, 354, 354, 355, 355, 358, 359, 361, 361, 370, 374,
       377, 386])

最后找到中位数(即将数据减半的值)。这就是作为len(x2_low)=15的选择。您可以说x2_low的中位数是它的第8个值(python中的索引7),然后:

代码语言:javascript
复制
> q = x2_low[int(len(x2_low)/2)]
336
> len(x2_low[x2_low<q])
7
> len(x2_low[x2_low>q])
7

这也是np.median(x2_low)甚至是q=np.percentile(x2,25,interpolation='lower')会返回的结果。但是你仍然会得到:

代码语言:javascript
复制
> len(x[x<q])/len(x)
0.2333333333334

由于你的数据量不是4的倍数,现在完全取决于你想要实现什么,以下是所有插值参数可以得到的结果:

linear:默认设置,您的问题中有此设置

lower:见上

higher

代码语言:javascript
复制
> q=np.percentile(x,25,interpolation='higher')
341
> len(x[x>q])/len(x)
0.7
> len(x[x<q])/len(x)
0.26666666666666666

nearest

代码语言:javascript
复制
> q=np.percentile(x,25,interpolation='nearest')
336
> len(x[x>q])/len(x)
0.7333333333333333
> len(x[x<q])/len(x)
0.23333333333333334

最后是midpoint

代码语言:javascript
复制
> q=np.percentile(x,25,interpolation='midpoint')
> len(x[x>q])/len(x)
0.7333333333333333
> len(x[x<q])/len(x)
0.26666666666666666

这完全取决于你之后想要做什么。有关不同计算方法的详细信息,请查看numpy's documentation

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55518198

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档