Сравнение двух массивов 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
элементы этого массива, чтобы определить, равны ли массивы, или есть более простой способ сравнения?
4 ответов
(A==B).all()
проверьте, все ли значения массива (A==B) истинны.
редактировать (из ответа дбауппа и комментария йоаврама)
следует отметить, что:
- данное решение может иметь странное поведение в конкретном случае: если либо
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
на (A==B).all()
решение очень аккуратное, но для этой задачи есть некоторые встроенные функции. А именно array_equal
, allclose
и array_equiv
.
(хотя, некоторые быстрое тестирование с timeit
указывают на то, что (A==B).all()
метод является самым быстрым, что немного странно, учитывая, что он должен выделить целый новый массив.)
давайте измерим производительность, используя следующий фрагмент кода.
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 метод.
если вы хотите проверить, имеют ли два массива одинаковые shape
и elements
вы должны использовать 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