Numpy условни аритметични операции върху два масива

Все още се опитвам да спечеля своите numpy stripes: Искам да извърша аритметична операция върху два 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