Условные арифметические операции Numpy над двумя массивами

Все еще пытаюсь заработать свои полоски numpy: я хочу выполнить арифметическую операцию над двумя массивами numpy, что достаточно просто:

return 0.5 * np.sum(((array1 - array2) ** 2) / (array1 + array2))

Проблема в том, что мне нужно указать условие, что, если оба массива поэлементно равны 0 в одном и том же элементе i, вообще не выполнять операцию - было бы здорово просто вернуть 0 для этого - чтобы не делить на 0.

Однако я понятия не имею, как указать это условие, не прибегая к ужасному вложенному циклу for. Спасибо заранее за помощь.

Изменить. Также было бы идеально не прибегать к псевдосчетчику +1.


person Magsol    schedule 15.03.2011    source источник


Ответы (3)


Просто замените np.sum() на np.nansum():

return 0.5 * np.nansum(((array1 - array2) ** 2) / (array1 + array2))

np.nansum() рассматривает nans как ноль.

person Sven Marnach    schedule 15.03.2011

return numpy.select([array1 == array2, array1 != array2], [0.5 * np.sum(((array1 - array2) ** 2) / (array1 + array2)), 0])

должно помочь... numpy.where также можно использовать.

person Benjamin    schedule 15.03.2011
comment
Это отличная идея (не знал, что я могу это сделать), но разве это не должно быть numpy.select([array1 == 0.0 and array2 == 0.0, array1 != array2], ...) для первого условия? - person Magsol; 16.03.2011
comment
Да, я не уловил это с первого раза. Вы можете сделать (массив1 == 0) * (массив2 == 0) для первого условия. Однако решение Свена кажется даже лучше. - person Benjamin; 16.03.2011

Вы также можете попробовать применить пост-применение numpy.nan_to_num:

http://docs.scipy.org/doc/numpy/reference/generated/numpy.nan_to_num.html

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

Если вы хотите пропустить сумму, когда у вас есть деление на ноль, вы также можете просто выполнить расчет, а затем проверить NaN перед возвратом:

xx = np.sum(((array1 - array2) ** 2) / (array1 + array2))
if np.isnan(xx):
    return 0
else:
    return xx 

Редактировать: чтобы отключить предупреждения, попробуйте повозиться с numpy.seterr:

http://docs.scipy.org/doc/numpy/reference/generated/numpy.seterr.html

person JoshAdel    schedule 15.03.2011
comment
Это очень хорошее предложение. Моя единственная жалоба здесь заключается в том, что мне все равно придется отключать каскадные предупреждения, когда происходит деление на ноль. - person Magsol; 16.03.2011
comment
@Magsol: Почему есть предупреждения? NumPy должен фактически делить на ноль без жалоб и просто давать NaN. - person Sven Marnach; 16.03.2011
comment
@Sven: я считаю, что предупреждение является новым с numpy 1.5. - person JoshAdel; 16.03.2011
comment
Не нужно возиться, просто old_setting= np.seterr(divide= 'ignore') должно быть достаточно. Спасибо - person eat; 16.03.2011