用python中的分位数索引替换numpy数组中的条目

时间:2016-11-23 16:45:01

标签: python performance numpy vectorization quantile

我有一个带有数字的一维numpy数组,我希望用它所属的分位数的索引替换每个数字。

这是我的五分指数代码:

import numpy as np

def get_quintile_indices( a ):

    result = np.ones( a.shape[ 0 ] ) * 4

    quintiles = [
        np.percentile( a, 20 ),
        np.percentile( a, 40 ),
        np.percentile( a, 60 ),
        np.percentile( a, 80 )
    ]

    for q in quintiles:
        result -= np.less_equal( a, q ) * 1

    return result

a = np.array( [ 58, 54, 98, 76, 35, 13, 62, 18, 62, 97, 44, 43 ] )
print get_quintile_indices( a )

输出:

[ 2.  2.  4.  4.  0.  0.  3.  0.  3.  4.  1.  1.]

你看我开始时使用最高可能索引初始化的数组以及每个条目的每个五分位数切割点减去1,该数据小于或等于五分位数。有一个更好的方法吗?一个内置函数,可用于将数字映射到一个切割点列表?

1 个答案:

答案 0 :(得分:3)

首先,我们可以一次性生成quintiles -

quintiles = np.percentile( a, [20,40,60,80] )    

要获得抵消的最后一步,我们可以简单地使用np.searchsorted,这可能是您正在寻找的内置,就像这样 -

out = np.searchsorted(quintiles, a)

或者,将循环代码直接转换为矢量化版本将使用broadcasting,就像这样 -

# Use broadcasting to perform those comparisons in one go.
# Then, simply sum along the first axis and subtract from 4. 
out = 4 - (quintiles[:,None] >=  a).sum(0)

如果quintiles是一个列表,我们需要将其指定为数组,然后使用broadcasting,就像这样 -

out = 4 - (np.asarray(quintiles)[:,None] >=  a).sum(0)