Применение функции в массиве NumPy дает разные ответы в разных запусках - PullRequest
0 голосов
/ 11 января 2019

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

Вот этот массивный вопрос (https://filebin.net/c14dcklwakrv1hw8)

import numpy as np
example = np.load("example_array.npy") #Shape (2, 5, 5)

Проблема, которую я пытался решить, состояла в том, чтобы нормализовать значения в каждой строке так, чтобы они суммировались в 1, за исключением, конечно, строк, которые целиком равны 0. Так как при разделении numpy есть возможность пропустить нули при делении функции, которую я использовал, был

f = lambda x: np.divide(x, np.sum(x, axis=1)[:, np.newaxis], where=np.sum(x, axis=1)[:, np.newaxis]!=0)

Что происходит, однако, это то, что значение f(example[1]) изменяется в зависимости от того, запущен ли example[1] или example[0] в терминале python перед ним. Поэтому, если вы запустите example[0], введите f(example[1]), последняя строка example[0] заменит первую строку ответа.

Выполнение этого можно увидеть здесь https://imgur.com/lzyHV8n

Python версия - 3.6.6, numpy - 1.15.3

Редактировать: - Добавление 1 ко всем элементам матрицы и повторение одной и той же операции без условия where в np.divide работает без проблем. Я думаю, что это источник ошибки, но я не знаю, почему это происходит

1 Ответ

0 голосов
/ 11 января 2019

Проблема в вашей функции заключается в вызове where. numpy.divide () выполнит базовый ufunc (фактический вызов функции, векторизованный в вызове numpy.divide) ТОЛЬКО в местах, где ваш оператор , где оценивается как true.

В других местах он помещает в память все, что у него есть, для заполнения создаваемого им массива. Чтобы получить хороший вывод, вам нужно использовать аргумент out в функции np.divide (см. Документ здесь: https://docs.scipy.org/doc/numpy-1.15.1/reference/generated/numpy.divide.html). Ниже приведен пример реализации с использованием определенной функции (ваш исходная функция также там для справки):

import numpy as np
e = np.load("example_array.npy")

def normalize_badversion(x):
    idx = np.sum(x, axis=1)[:, np.newaxis]
    return np.divide(x, idx, where=idx!=0)

def normalize(x):
    idx = np.sum(x, axis=1)[:, np.newaxis]
    return np.divide(x, idx, where=idx!=0, out=np.zeros_like(x))

print e[0]
a = normalize(e[1])
print e[1]
b = normalize(e[1])
print np.allclose(a,b)


print e[0]
a = normalize_badversion(e[1])
print e[1]
b = normalize_badversion(e[1])
print np.allclose(a,b)

Последнее замечание: я согласен с тем, что нынешний документ о неразберихе не совсем ясен по этому вопросу. Недавнее исправление было выдвинуто в простом документе, чтобы прояснить это, см. https://github.com/numpy/numpy/commit/9a82c53c8a2b9bd4798e515544de4a701cbfba3f

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