Сравнение двух массивов numpy для равенства, по элементам
Каков самый простой способ сравнить два массива numpy для равенства (где равенство определено как: A = B iff для всех индексов i: A[i] == B[i]
)?
Просто используя ==
дает мне логический массив:
>>> numpy.array([1,1,1]) == numpy.array([1,1,1])
array([ True, True, True], dtype=bool)
Нужно ли мне and
использовать элементы этого массива, чтобы определить, равны ли массивы или есть более простой способ сравнения?
Ответы
Ответ 1
(A==B).all()
проверьте, являются ли все значения массива (A == B) равными True.
Изменить (из ответа dbaupp и комментария yoavram)
Следует отметить, что:
- это решение может иметь странное поведение в конкретном случае: если либо
A
, либо B
пуст, а другой содержит один элемент, то он возвращает True
. По какой-то причине сравнение A==B
возвращает пустой массив, для которого оператор all
возвращает True
.
- Другой риск заключается в том, что если
A
и B
не имеют одинаковой формы и не передаются в широковещательном режиме, тогда этот подход вызовет ошибку.
В заключение, решение, которое я предложил, является стандартным, я думаю, но если у вас есть сомнения относительно формы A
и B
или просто хотите быть в безопасности: используйте одну из специализированных функций:
np.array_equal(A,B) # test if same shape, same elements values
np.array_equiv(A,B) # test if broadcastable shape, same elements values
np.allclose(A,B,...) # test if same shape, elements have close enough values
Ответ 2
Решение (A==B).all()
очень аккуратное, но для этой задачи есть встроенные функции. А именно array_equal
, allclose
и array_equiv
.
(Хотя некоторые быстрые тесты с timeit
, по-видимому, указывают на то, что метод (A==B).all()
является самым быстрым, что немного странно, поскольку ему нужно выделить целый новый массив.)
Ответ 3
Позвольте измерить производительность, используя следующий фрагмент кода.
import numpy as np
import time
exec_time0 = []
exec_time1 = []
exec_time2 = []
sizeOfArray = 5000
numOfIterations = 200
for i in xrange(numOfIterations):
A = np.random.randint(0,255,(sizeOfArray,sizeOfArray))
B = np.random.randint(0,255,(sizeOfArray,sizeOfArray))
a = time.clock()
res = (A==B).all()
b = time.clock()
exec_time0.append( b - a )
a = time.clock()
res = np.array_equal(A,B)
b = time.clock()
exec_time1.append( b - a )
a = time.clock()
res = np.array_equiv(A,B)
b = time.clock()
exec_time2.append( b - a )
print 'Method: (A==B).all(), ', np.mean(exec_time0)
print 'Method: np.array_equal(A,B),', np.mean(exec_time1)
print 'Method: np.array_equiv(A,B),', np.mean(exec_time2)
Выход
Method: (A==B).all(), 0.03031857
Method: np.array_equal(A,B), 0.030025185
Method: np.array_equiv(A,B), 0.030141515
В соответствии с вышеприведенными результатами методы numpy выглядят быстрее, чем комбинация оператора == и метода all() и путем сравнения методов numpy Самый быстрый - это метод numpy.array_equal.
Ответ 4
Если вы хотите проверить, имеют ли два массива одинаковые elements
shape
AND, вы должны использовать np.array_equal
как это метод, рекомендованный в документации.
С точки зрения производительности не ожидайте, что любая проверка на равенство побьет другую, так как не так много места для оптимизации comparing two elements
. Просто ради этого я все же провел несколько тестов.
import numpy as np
import timeit
A = np.zeros((300, 300, 3))
B = np.zeros((300, 300, 3))
C = np.ones((300, 300, 3))
timeit.timeit(stmt='(A==B).all()', setup='from __main__ import A, B', number=10**5)
timeit.timeit(stmt='np.array_equal(A, B)', setup='from __main__ import A, B, np', number=10**5)
timeit.timeit(stmt='np.array_equiv(A, B)', setup='from __main__ import A, B, np', number=10**5)
> 51.5094
> 52.555
> 52.761
Так что в равной степени, не нужно говорить о скорости.
(A==B).all()
ведет себя почти так же, как следующий фрагмент кода:
x = [1,2,3]
y = [1,2,3]
print all([x[i]==y[i] for i in range(len(x))])
> True
Ответ 5
Обычно два массива будут иметь небольшие числовые ошибки,
Вы можете использовать numpy.allclose(A,B)
вместо (A==B).all()
. Возвращает bool True/False