Ошибка трансляции при переклассификации массива с плавающей точкой с использованием векторизованной функции - PullRequest
0 голосов
/ 18 апреля 2019

Я хочу оценить каждое значение в двумерном массиве чисел с плавающей запятой, если оно попадает в минимальные, максимальные границы определенного числового класса.Далее я хочу переназначить это значение на «оценку», связанную с этим классом.

Например, границы классов могут быть:

>>> class1 = (0, 1.5)
>>> class2 = (1.5, 2.5)
>>> class3 = (2.5, 3.5)

Баллы классов:

>>> score1 = 0.75
>>> score2 = 0.50
>>> score3 = 0.25

Значения вне любого из классов должны по умолчанию равны, например, 99.

Я пробовал следующее, но столкнулся с ошибкой ValueError из-за широковещательной рассылки.

>>> import numpy as np

>>> arr_f = (6-0)*np.random.random_sample((4,4)) + 0  # array of random floats


>>> def reclasser(x, classes, news):
>>>     compare = [x >= min and x < max for (min, max) in classes]
>>>     try:
>>>         return news[compare.index(True)
>>>     except Value Error:
>>>         return 99.0


>>> v_func = np.vectorize(reclasser)
>>> out = v_func(arr_f, [class1, class2, class3], [score1, score2, score3])

ValueError: operands could not be broadcast together with shapes (4,4) (4,2) (4,) 

Любые предложения о причинах возникновения этой ошибки и способах ее исправления были бы весьма полезны.Кроме того, если я нахожусь на неправильном пути, используя векторизованные функции, я также был бы рад услышать это.

1 Ответ

1 голос
/ 18 апреля 2019

Попробуйте сначала заставить код работать без использования np.vectorize.Приведенный выше код не будет работать даже с одним float в качестве первого аргумента.Вы ошиблись ValueError;также не рекомендуется использовать min и max в качестве имен переменных (это функции Python).Фиксированная версия reclasser будет выглядеть следующим образом:

def reclasser(x, classes, news):
    compare = [min(cls) < x < max(cls) for cls in classes]
    try:
        return news[compare.index(True)]
    except ValueError:
        return 99.0

Тем не менее, я думаю, что использование reclasser и np.vectorize излишне сложно.Вместо этого вы можете сделать что-то вроде:

# class -> score mapping as a dict
class_scores = {class1: score1, class2: score2, class3: score3}
# matrix of default scores
scores = 99 * np.ones(arr_f.shape)

for cls, score in class_scores.items():
    # see which array values belong into current class
    in_cls = np.logical_and(cls[0] < arr_f, arr_f < cls[1])
    # update scores for current class
    scores[np.where(in_cls)] = score

scores будет тогда массивом оценок, соответствующим исходному массиву данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...