2015-09-30 20 views
8

Chcę przetestować, czy dwie wyskakujące tablice są (zbliżone do) równe, więc korzystam z funkcji np.allclose. Jedyny problem polega na tym, że zwraca on True, jeśli otrzyma dwuwymiarową macierz i trójwymiarową macierz równych elementów.Sprawdź, czy dwie niezliczone tablice są (zbliżone do) sobie równe, w tym kształt

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. 

Teraz wiem o np.array_equal, który porównuje elementy i kształt, ale nie pozwala mi sprawdzić, czy elementy są blisko, tylko jeśli są one równe. Na przykład,

np.array_equal(x,y) 

Zwraca False

Czy istnieje funkcja mogę używać że zwróci true dla (x,y) i (z1,z2) ale fałszywy dla (x,z1) w tym przypadku?

+4

Co powiecie na dodanie jeszcze jednego czeku - '(x.shape == z1.shape) & np.allclose (x, z1)'? – Divakar

Odpowiedz

9

Co się dzieje, że allclose nadaje swój sygnał wejściowy. Umożliwia to porównanie z podobnie ukształtowanymi macierzami (na przykład 3 i [3, 3, 3]) po broadcasting rules.


Dla swoich celów, przyjrzeć się funkcji numpy.testing, a konkretnie np.testing.assert_allclose lub assert_array_almost_equal, który będzie sprawdzał kształt oraz wartości. (Nie pamiętam różnicy między tymi dwoma metodami, ale dotyczy to sposobu, w jaki obliczają różnice zmiennoprzecinkowe.)

Są to szczególnie przydatne, jeśli używasz testów jednostkowych opartych na assert.

Większość (wszystkie?) Funkcji numpy.testing.assert_* sprawdza kształt tablicy oraz równość wartości.

Na przykład:

In [1]: import numpy as np 

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

co daje:

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

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

Inną użyteczną (a obecnie nie jest tak dobrze udokumentowane, jak to może być) coś wiedzieć o tych funkcji jest to, że porównanie ich NaN ' s jak równy.

Na przykład, to uda:

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

Podczas numpy.allclose powróci False dla tej samej sprawie:

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

Na marginesie, numpy.isclose (ale nie allclose) ma equal_nan kwarg kontrolować to.

+0

Wykonuję testy jednostkowe oparte na assertach, więc to działa idealnie. Dzięki –

+0

Zauważ, że 'np.testing.assert_allclose (1, [1, 1])' i podobne wciąż przechodzą: pojedynczy float (numpy skalar, 'np.array (1)') jest nadal emitowany. Być może dlatego, że nie mają one atrybutu "shape" (lub takiego, który jest pustą krotką). – Evert

Powiązane problemy