Возвращает нулевое значение, если встречается деление на ноль

У меня есть два списка a и b одинаковой длины. Я хочу рассчитать сумму их отношения:

c = np.sum(a/b)

как я могу иметь нулевое (0) значение в коэффициенте суммирования, когда есть деление на ноль?

РЕДАКТИРОВАТЬ: Вот несколько ответов, которые я проверил для своего случая, и все еще вызываю ошибку. Наверное, я что-то упускаю. Массив, содержащий нулевые элементы, равен counts:

try:
    cnterr = (counts/np.mean(counts))*(((cnterr/counts)**2 + (meanerr/np.mean(counts))**2 ))**1/2
except ZeroDivisionError:
    cnterr = (counts/np.mean(counts))*(((meanerr/np.mean(counts))**2 ))**1/2

RuntimeWarning: divide by zero encountered in divide
cnterr = (counts/np.mean(counts))*(((cnterr/counts)**2 + (meanerr/np.mean(counts))**2 ))**1/2

А также от np.where():

cnterr = np.where(counts != 0, ((counts/np.mean(counts))*(((cnterr/counts)**2 + (meanerr/np.mean(counts))**2 ))**1/2), 0)

Выдает ту же ошибку.


person Py-ser    schedule 17.04.2014    source источник


Ответы (5)


Чтобы суммировать значения, кроме divide by 0,

sel = b != 0
c = np.sum(a[sel]/b[sel])

Массивы float, вам может понадобиться использовать

sel = np.bitwise_not(np.isclose(b, 0))

ОБНОВЛЕНИЕ

Если a и b не np.array, напишите следующий код в первом.

a = np.array(a)
b = np.array(b)
person emeth    schedule 17.04.2014
comment
+1 Лучший ответ на данный момент, с несколькими совершенно неправильными ответами, а другие не используют преимущества numpy ;-) Похоже, вопрос не был понят. - person ; 17.04.2014
comment
Примечание. a и b необходимо сначала преобразовать в массивы numpy (OP заявляет, что это списки) - person atomh33ls; 17.04.2014
comment
Для np.isclose вы можете применить правила вещания, и оно будет работать как положено np.isclose(b, 0). - person Daniel; 17.04.2014
comment
Возвращает ли это массив с номерами элементов, отличными от a и b ? - person Py-ser; 18.04.2014
comment
возвращается scalar, который является результатом суммирования a[i]/b[i] для всех i, кроме b == 0. - person emeth; 18.04.2014
comment
Конечно, извините, моя вина (я думал о другом применении этого решения) - person Py-ser; 18.04.2014

c = np.where(b != 0, a/b, 0).sum()

См.: http://docs.scipy.org/doc/numpy/reference/generated/numpy.where.html

person YXD    schedule 17.04.2014
comment
Это всего лишь предупреждение, но оно может раздражать. На самом деле, where в numpy, как и любая другая функция, предполагает, что оба аргумента вычисляются, в отличие от where в Fortran (оператор, а не функция), который будет вычислять деление только в том случае, если b!=0. - person ; 18.04.2014

Это работает, он помещает 0 в список, где есть деление на ноль:

c = np.sum([x/y if y else 0 for x,y in zip(a,b)])

Или вариант ответа @mskimm. Обратите внимание: сначала вам нужно преобразовать ваши входные списки в массивы numpy:

a=np.array(a)
b=np.array(b)
c=np.sum(a[b!=0]/b[b!=0])
person atomh33ls    schedule 17.04.2014

Это должно работать.

c = []
for i, j in enumerate(a):
    if b[i] != 0:
        c += [j/b[i]]
    else:
        c += [0]

c = sum(c)
person John B    schedule 17.04.2014
comment
хм, у меня есть np (Python 2.7) - person atomh33ls; 17.04.2014
comment
Если я переопределю a и b как массивы 1D numpy, я получу ValueError: - person atomh33ls; 17.04.2014
comment
Да, это то, что я сделал сначала для ошибки типа, два списка целых чисел... a=[1, 2, 3, 4], b=[4, 0, 6, 2] - person atomh33ls; 17.04.2014
comment
Вы правы, спасибо, что указали на это. Я что-то упустил в вопросе. Мой обновленный ответ должен работать. - person John B; 17.04.2014
comment
Да :-)... Я думаю, вам просто нужно c=np.sum(c) в конце - person atomh33ls; 17.04.2014
comment
@John B. Дело в том, чтобы использовать numpy. Поскольку у него есть эффективный способ фильтрации массивов, зачем изобретать колесо и (возможно) более медленное колесо? - person ; 17.04.2014
comment
Извините, я новичок в python и не знаком с numpy. Теперь я знаю :D - person John B; 17.04.2014

Это тоже просто:

c = 0 if 0 in b else sum(a/b)
person ssm    schedule 17.04.2014
comment
Это устанавливает c в ноль, если где-то в b есть ноль - а не то, что хочет OP (если я неправильно истолковал). - person atomh33ls; 17.04.2014