Вопрос по python, arrays, numpy – Сравнение двух пустых массивов для равенства, поэлементно

166

Какой самый простой способ сравнить два числа-пустышки на равенство (где равенство определяется как: A = B тогда и только для всех индексов i:A[i] == B[i])?

Просто используя== дает мне логический массив:

 >>> numpy.array([1,1,1]) == numpy.array([1,1,1])

array([ True,  True,  True], dtype=bool)

Должен ли яand элементы этого массива, чтобы определить, равны ли массивы, или есть более простой способ сравнения?

Ваш Ответ

4   ответа
251
(A==B).all()

Edit (из ответа dbaupp и комментария yoavram)

Следует отметить, что:

this solution can have a strange behavior in a particular case: if either A or B is empty and the other one contains a single element, then it return True. For some reason, the comparison A==B returns an empty array, for which the all operator returns True. Another risk is if A and B don't have the same shape and aren't broadcastable, then this approach will raise an error.

В заключение, решение, которое я предложил, является стандартным, я думаю, но если у вас есть сомнения по поводу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
Вы почти всегда хотитеnp.array_equal IME.(A==B).all() будутcrash if A and B have different lengths, По состоянию на 1.10,== raises a deprecation warning in this case.
Я не понимаю это поведениеimport numpy as np H = 1/np.sqrt(2)*np.array([[1, 1], [1, -1]]) #hadamard matrix np.array_equal(H.dot(H.T.conj()), np.eye(len(H))) # checking if H is an unitary matrix or not  H унитарная матрица, поэтому H xH.T.conj это единичная матрица. Ноnp.array_equal возвращает Ложь
Вы получили хорошую оценку, но в случае, если у меня есть сомнения относительно формы, я обычно предпочитаю непосредственно проверить ее, прежде чем значение. Тогда ошибка явно связана с формами, которые имеют совершенно другое значение, чем имеющие разные значения. Но это, вероятно, зависит от каждого варианта использования
Хорошо отметить это. Тем не менее, я думаю, что это логично, потому чтоnan!=nan подразумевает, чтоarray(nan)!=array(nan).
Другой риск, если массивы содержат Nan. В этом случае вы получите False, потому что nan! = Nan
13

используя следующий фрагмент кода.

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)

Output

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 методыthe fastest один кажетсяnumpy.array_equal метод.

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

(A==B).all() Решение очень аккуратное, но для этой задачи есть несколько встроенных функций. а именноarray_equal, allclose а такжеarray_equiv.

(Хотя, некоторые быстрые испытания сtimeit кажется, указывает на то, что(A==B).all() метод является самым быстрым, что немного странно, учитывая, что он должен выделить целый новый массив.)

вы правы, за исключением того, что если один из сравниваемых массивов пуст, вы получите неправильный ответ с(A==B).all(), Например, попробуйте:(np.array([1])==np.array([])).all(), это даетTrue, в то время какnp.array_equal(np.array([1]), np.array([])) даетFalse
Я только что обнаружил эту разницу в производительности тоже. Это странно, потому что если у вас есть 2 совершенно разных массива(a==b).all() все еще быстрее чемnp.array_equal(a, b) (который мог просто проверить один элемент и выйти).
np.array_equal также работает сlists of arrays а такжеdicts of arrays, Это может быть причиной снижения производительности.
Большое спасибо за функциюallcloseэто то, что мне нужно дляnumerical расчеты. Он сравнивает равенство векторов в пределахtolerance. :)
9

shape А ТАКЖЕelements вы должны использоватьnp.array_equal так как это метод, рекомендуемый в документации.

Performance-wise don't expect that any equality check will beat another, as there is not much room to optimize comparing two elements. Just for the sake, i still did some tests.

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

Похожие вопросы