np.quantile计算错误?

时间:2019-04-04 14:16:12

标签: python numpy

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

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))

输出:

337.25

0.26666666666666666

0.7333333333333333

0.73表示仅73%的值大于或等于确定的分位数;根据定义,它应该>> 75%

2 个答案:

答案 0 :(得分:1)

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

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 :(得分:1)

正如@SamProell所述,计算百分位数有不同的约定,如您所见,here with quartile's computing methods(美国方式)。在这里,我们有偶数个数据,所以我们坚持第一种方法,然后尝试看看我们将如何“手工”完成该工作。

首先,对数据进行排序:

> 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])

然后将数据分为两半:

> 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),然后:

> 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')返回的结果。但是您仍然会得到:

> len(x[x<q])/len(x)
0.2333333333334

由于数据数量不是4的倍数,所以现在这一切都取决于要实现的结果,这是您可以为所有插值参数获得的结果:

linear:默认值是您输入的问题

lower:请参见上文

higher

> 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

> 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

> 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