【问题标题】:Numpy: vectorize assigment of values based on conditionsNumpy:根据条件向量化赋值
【发布时间】:2019-07-04 04:46:55
【问题描述】:

考虑以下函数:

import numpy
import scipy.stats


def return_category(values, categories):
    n = len(categories)

    result = numpy.empty(values.shape, dtype='U25')

    boundaries = scipy.stats.norm.ppf(numpy.arange(0, n+1, 1)/n)
    for i, category in enumerate(categories):
        a, b = boundaries[i], boundaries[i + 1]
        numpy.putmask(result, (values < b) & (values >= a), category)

    return result


print(return_category(numpy.array([0.1, -100, 100, 0.44]), ['a', 'b', 'c']))
# ['b' 'a' 'c' 'c']

即它根据值的位置从类别列表中分配一个类别,这样如果values 来自正态分布 (0, 1),则每个类别的概率均等。

问题是:我如何向量化它?即如何摆脱需要大量更改(对于大量类别和值)的循环。

这个问题可以更一般地表述为:有一个映射M={I1: c1, I2: c2, ...},其中Ii是一个区间,所有区间的并集是]-inf,inf[,它们的交集是空的,ci是一个类别.给定一个值数组[a1, a2, ..., aM],创建一个新数组

[
 M[Ii such that a1 in Ii],
 M[Ii such that a2 in Ii], 
 ...
 M[Ii such that aM in Ii],
]

在上述特定情况下,间隔为scipy.stats.norm.ppf(numpy.arange(0, n+1, 1)/n)

【问题讨论】:

    标签: python numpy


    【解决方案1】:

    我认为这可能会满足您的需求:

    import numpy 
    import scipy.stats
    
    
    def return_category(values, categories):
        n = len(categories)
        categories = numpy.array(categories)
        result = numpy.empty(values.shape, dtype='U25')
        boundaries = scipy.stats.norm.ppf(numpy.arange(0, n+1, 1)/n)
        # array of "left" boundaries
        bndrs0 = boundaries[:-1]
        # array of "right" boundaries
        bndrs1 = boundaries[1:]
        # build an array such that the j-th column in the
        # i-th row is True if the j-th column of values is in the i-th category
        whereCat = numpy.where(numpy.logical_and(values>=numpy.tile(bndrs0, (values.size,1)).T, values < numpy.tile(bndrs1, (values.size,1)).T))
        # broadcast categories to the corresponding rows
        sortedCats = numpy.take_along_axis(categories, whereCat[0],0)
        # place categories in the correct column
        numpy.put_along_axis(result,whereCat[1],sortedCats,0)
        return result
    
    
    print(return_category(numpy.array([0.1, -100, 100, 0.44]), ['a', 'b', 'c']))
    # ['b' 'a' 'c' 'c']
    

    【讨论】:

      猜你喜欢
      • 2018-12-08
      • 2020-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-17
      • 2018-06-15
      • 1970-01-01
      相关资源
      最近更新 更多