2015-09-30 2 views
8

Я хочу проверить, если два массива numpy (близкие к) равны, поэтому я использовал функцию np.allclose. Единственная проблема заключается в том, что она возвращает True, если задана двумерная матрица и трехмерная матрица равных элементов.Протестируйте, если два массива numpy (близкие к) равны, включая форму

import numpy as np 

x = np.array([[3.14159265, -0.1], [-0.1, 0.1]]) 

y = np.array([[math.pi, -0.1], [-0.1, 0.1]]) 

z1 = np.array([[[3.14159265, -0.1], [-0.1, 0.1]], 
       [[3.14159265, -0.1], [-0.1, 0.1]]]) 
z2 = np.array([[[math.pi, -0.1], [-0.1, 0.1]], 
       [[math.pi, -0.1], [-0.1, 0.1]]]) 


np.allclose(x,y) 
# Returns true, as expected 

np.allclose(x,z1) 
# Also returns true, even though matrices are different shapes. Unwanted. 

Теперь я знаю о np.array_equal, который сравнивает элементы и формы, но он не позволяет мне, чтобы проверить, если элементы близки, только если они равны. Так, например,

np.array_equal(x,y) 

Возвращает False

Есть ли функция, которую я могу использовать, что возвращает истину для (x,y) и (z1,z2), но неверно для (x,z1) в этом случае?

+4

Как насчет добавления еще одной проверки - '(x.shape == z1.shape) & np.allclose (x, z1)'? – Divakar

ответ

9

Что происходит, так это то, что allclose передает свои данные. Это позволяет сравнивать с массивами аналогичной формы (например, 3 и [3, 3, 3]), следуя broadcasting rules.


Для ваших целей, есть взгляд на numpy.testing функций, в частности np.testing.assert_allclose или assert_array_almost_equal, который будет проверять для формы, а также значений. (Я не помню разницу между этими двумя руками, но это связано с тем, как они вычисляют разницу в плавающей запятой.)

Это особенно удобно, если вы используете модульные испытания на основе утверждений.

Большинство функций (всего?) Функций numpy.testing.assert_* проверяют для формы массива, а также для равенства значений.

Например:

In [1]: import numpy as np 

In [2]: np.testing.assert_allclose([1], [[1]]) 

Что дает:

AssertionError: 
Not equal to tolerance rtol=1e-07, atol=0 

(shapes (1,), (1, 1) mismatch) 
x: array([1]) 
y: array([[1]]) 

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

Например, это будет иметь успех:

In [3]: np.testing.assert_allclose([np.nan], [np.nan]) 

Хотя numpy.allclose вернется False для того же случая:

In [4]: np.allclose([np.nan], [np.nan]) 
Out[4]: False 

На стороне записки, numpy.isclose (но не allclose) имеет equal_nan kwarg чтобы контролировать это.

+0

Я занимаюсь тестированием на основе утверждений, поэтому это работает отлично. Спасибо –

+0

Обратите внимание, что 'np.testing.assert_allclose (1, [1, 1])' и все еще проходят: по-прежнему передается один float (numpy scalar, 'np.array (1)'). Возможно, потому, что у них нет атрибута 'shape' (или того, который содержит пустой кортеж). – Evert