Лучший способ подтвердить равенство numpy.array?

104

Я хочу провести несколько модульных тестов для своего приложения, и мне нужно сравнить два массива. Поскольку array.__eq__возвращает новый массив (так что TestCase.assertEqualне удается), как лучше всего утверждать равенство?

В настоящее время я использую

self.assertTrue((arr1 == arr2).all())

но мне это не очень нравится

производитель
источник
1
обратите внимание, что ваш пример может неожиданно дать True, например, (np.array([1, 1]) == np.array([1])).all()вернет True
М. Бернхардт
1
self.assertTrue (np.array_equal (array1, array2))
Miszo97

Ответы:

120

проверьте функции assert numpy.testing, например

assert_array_equal

для массивов с плавающей запятой проверка на равенство может завершиться ошибкой и assert_almost_equalболее надежна.

Обновить

Несколько версий назад было получено numpy, assert_allcloseкоторое сейчас является моим любимым, поскольку оно позволяет нам указывать как абсолютную, так и относительную ошибку и не требует десятичного округления в качестве критерия близости.

Йозеф
источник
18
Как это взаимодействует с unittest? Думаю, было бы полезно сказать несколько слов по этому поводу.
Рамон Мартинес
Я никогда не использую unittest. Однако он очень хорошо работает с тестами на нос, которые используются моделями numpy, scipy и statsmodels. Просто используйте утверждения внутри тестовой функции или метода.
Josef
Это не подтверждает, что оба аргумента являются массивами numpy. Например, он будет успешным для массива и списка. Для тестирования может быть полезно проверить, действительно ли это массивы, но я предполагаю, что для этого потребуется вручную проверить тип?
максимум
4
@RamonMartinez assert_allclose, похоже, отлично работает с unittest :)
kotakotakota
4
@RamonMartinez, если вы используете Python, unittestвы можете использовать self.assertIsNone(np.testing.assert_array_equal(a, b))его, когда он возвращает, Noneесли массивы равны.
mjkrause
24

Думаю, (arr1 == arr2).all()выглядит неплохо. Но вы можете использовать:

numpy.allclose(arr1, arr2)

но это не совсем то же самое.

Альтернатива, почти такая же, как в вашем примере:

numpy.alltrue(arr1 == arr2)

Обратите внимание, что scipy.array на самом деле является ссылкой на numpy.array. Это упрощает поиск документации.

SiggyF
источник
18

Я нахожу это с помощью self.assertEqual(arr1.tolist(), arr2.tolist()) - это самый простой способ сравнения массивов с помощью unittest.

Я согласен, что это не самое красивое решение и, вероятно, не самое быстрое, но, вероятно, оно более единообразно с остальными вашими тестовыми примерами, вы получаете все описание ошибок unittest, и его действительно просто реализовать.

Asimoneau
источник
1
Обратите внимание , что это не будет хорошо работать с np.nan, так np.nan != np.nanи self.assertEqualпопытка не будет в состоянии счета для этого.
Blacksite
5

Начиная с Python 3.2 вы можете использовать assertSequenceEqual(array1.tolist(), array2.tolist()).

Это имеет дополнительную ценность, показывая вам точные элементы, в которых различаются массивы.

HagaiH
источник
5
К сожалению, это не работает, когда массивы имеют floatтип. Нам действительно нужноassertSequenceAlmostEqual
grwlf
4

В своих тестах я использую это:

try:
    numpy.testing.assert_array_equal(arr1, arr2)
    res = True
except AssertionError as err:
    res = False
    print (err)
self.assertTrue(res)
Пользователь Edo1419293
источник
1

np.linalg.norm(arr1 - arr2) < 1e-6

Schiebermc
источник
4
Пожалуйста, добавьте немного контекста
Тобиас Уилферт