【问题标题】:how does numpy find the median in an array/list?numpy 如何在数组/列表中找到中位数?
【发布时间】:2021-03-17 23:34:34
【问题描述】:

我读到,numpy 使用 introselect 在数组/列表中查找中位数 (https://www.researchgate.net/publication/303755458_Fast_Deterministic_Selection) [第 2 页;最后 5 行]。但我在 numpy 源代码中找不到任何提示:https://github.com/numpy/numpy/blob/v1.19.0/numpy/lib/function_base.py#L3438-L3525

有谁知道我在哪里可以找到 introselect 的 numpy 实现?或者如果numpy不使用introselect,使用什么样的算法来找到中位数?

提前非常感谢:)

【问题讨论】:

    标签: python algorithm numpy median


    【解决方案1】:

    第 3528 行似乎是主要的中位函数。如果我们去掉所有多维和 nan 的东西,我们会得到类似的东西

    def _median(a, axis=None, out=None, overwrite_input=False):
        # can't be reasonably be implemented in terms of percentile as we have to
        # call mean to not break astropy
    
        # Set the partition indexes
        sz = a.shape
        if sz % 2 == 0:
            szh = sz // 2
            kth = [szh - 1, szh]
        else:
            kth = [(sz - 1) // 2]
    
        part = partition(a, kth, axis=None)
    
        return mean(part[indexer], axis=None, out=out)
    

    所以分区正在做所有的工作并且来自

    from numpy.core.fromnumeric import (
        ravel, nonzero, partition, mean, any, sum
        )
    

    如果我们转到 numpy 代码,我们会得到以下 C code

    NPY_SELECTKIND sortkind = NPY_INTROSELECT;
    

    val = PyArray_Partition(self, ktharray, axis, sortkind);
    

    实现here并使用

    mid = ll + median_of_median5_@suff@(v + ll, hh - ll, NULL, NULL);
    

    所以它是 introselect。

    一旦达到递归深度的两倍,算法就会更改为使用中位数5,直到分区小于5。

    【讨论】:

    • 您好,感谢您的回答。我不确定这是否具体,但你知道他们使用什么样的标准来决定他们是否应该切换到中位数的中位数?他们在 C 代码的第 341 行中说:depth_limit = npy_get_msb(num) * 2;后来: ll = low + 1 和 hh = high (行:345)但是 ll 和 hh 有什么样的起始值? depth_limit 有什么值或者它是如何计算的。 (我很抱歉这个有点“愚蠢”的问题,但我对 C 不是很熟悉)
    • @maxpower 它在数组中的低位和高位,缩小仍然需要分区的部分。
    • depth_limit 是如何计算的?或者更具体地说,npy_get_msb(num) 是什么意思,num 的值是什么?非常感谢,你帮了我很多:)
    • msb - 最高有效位,多少次可以减半。
    猜你喜欢
    • 2017-12-23
    • 1970-01-01
    • 2014-04-03
    • 2019-05-06
    • 2012-05-07
    • 2019-07-05
    • 2022-11-01
    • 1970-01-01
    相关资源
    最近更新 更多