【问题标题】:Replacing entries in a numpy array with their quantile index with python用python用它们的分位数索引替换numpy数组中的条目
【发布时间】:2017-04-07 18:55:01
【问题描述】:

我有一个带有数字的一维 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。有一个更好的方法吗?可用于将数字映射到切点列表的内置函数?

【问题讨论】:

    标签: python performance numpy vectorization quantile


    【解决方案1】:

    首先,我们可以一次性生成那些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)
    

    【讨论】:

    • 应该是out = np.searchsorted( quintiles, a )
    • @daign 如果我们用np.percentile( a, [20,40,60,80] ) 生成quintiles,那么quintiles 将是一个数组,那么quintiles.searchsorted(a) 也可以工作。但是是的,如果quintiles 是一个类似于您在代码中的方式的列表,那么我们需要使用np.searchsorted( quintiles, a )
    • 奇怪的是np.percentile( a, [20,40,60,80] ) 没有给我一个数组,而是一个列表。 python版本之间有区别吗?我正在使用 Python 2.7.3
    • @daign 你的 NumPy 版本是多少?
    • >>> numpy.version.version '1.6.1' 因为我还在用 Ubuntu 12.04 :)
    猜你喜欢
    • 1970-01-01
    • 2014-10-01
    • 1970-01-01
    • 2015-10-31
    • 1970-01-01
    • 2012-11-14
    • 2015-03-10
    • 2023-01-27
    • 1970-01-01
    相关资源
    最近更新 更多