15

how should i compare more than 2 numpy arrays?

import numpy 
a = numpy.zeros((512,512,3),dtype=numpy.uint8)
b = numpy.zeros((512,512,3),dtype=numpy.uint8)
c = numpy.zeros((512,512,3),dtype=numpy.uint8)
if (a==b==c).all():
     pass

this give a valueError, and i am not interested in comparing arrays two at a time.

2
  • 3
    "and i am not interested in comparing arrays two at a time" - well, it's the best option you have. Commented Jun 12, 2016 at 18:17
  • @user2357112 that wouldn't be easy if there are many arrays Commented Jun 12, 2016 at 18:22

6 Answers 6

12

For three arrays, you can check for equality among the corresponding elements between the first and second arrays and then second and third arrays to give us two boolean scalars and finally see if both of these scalars are True for final scalar output, like so -

np.logical_and( (a==b).all(), (b==c).all() )

For more number of arrays, you could stack them, get the differentiation along the axis of stacking and check if all of those differentiations are equal to zeros. If they are, we have equality among all input arrays, otherwise not. The implementation would look like so -

L = [a,b,c]    # List of input arrays
out = (np.diff(np.vstack(L).reshape(len(L),-1),axis=0)==0).all()
Sign up to request clarification or add additional context in comments.

2 Comments

what is the need of reshape(len(L),-1), it works well even without that
@JayanthReddy No, it doesn't. That axis would contain the first axis from the input arrays merged with the axis of stacking. So, we need to split that axis into two with that reshaping. To clarify with an example, try out with a = np.random.randint(0,9,(4,5,3)); b = a.copy(); c = a.copy().
8

For three arrays, you should really just compare them two at a time:

if np.array_equal(a, b) and np.array_equal(b, c):
    do_whatever()

For a variable number of arrays, let's suppose they're all combined into one big array arrays. Then you could do

if np.all(arrays[:-1] == arrays[1:]):
    do_whatever()

1 Comment

@JayanthReddy: Probably because you made arrays a list or something.
7

To expand on previous answers, I would use combinations from itertools to construct all pairs, then run your comparison on each pair. For example, if I have three arrays and want to confirm that they're all equal, I'd use:

from itertools import combinations

for pair in combinations([a, b, c], 2):
    assert np.array_equal(pair[0], pair[1])

3 Comments

constructing all pairs is not necessary (since a=b and b=c would imply a=c). A simple for loop comparing 2 arrays at a time would be more computationally efficient.
That's correct! This is explicitly inefficient. Just a method for intuitively/transparently comparing each item to the others.
This answer is useful for float arrays where you'd want to use allclose instead of array_equal; allclose is not transitive. @Elsewhere Maybe you could expand your answer based on that since the question doesn't explicitly ask for comparing for equality and neither restricts to int arrays.
1

solution supporting different shapes and nans

compare against first element of array-list:

import numpy as np

a = np.arange(3)
b = np.arange(3)
c = np.arange(3)
d = np.arange(4)

lst_eq = [a, b, c]
lst_neq = [a, b, d]

def all_equal(lst):
    for arr in lst[1:]:
        if not np.array_equal(lst[0], arr, equal_nan=True):
            return False
    return True

print('all_equal(lst_eq)=', all_equal(lst_eq))
print('all_equal(lst_neq)=', all_equal(lst_neq))

output

all_equal(lst_eq)= True
all_equal(lst_neq)= False

for equal shape and without nan-support

Combine everything into one array, calculate the absolute diff along the new axis and check if the maximum element along the new dimension is equal 0 or lower than some threshold. This should be quite fast.

import numpy as np

a = np.arange(3)
b = np.arange(3)
c = np.arange(3)
d = np.array([0, 1, 3])

lst_eq = [a, b, c]
lst_neq = [a, b, d]

def all_equal(lst, threshold = 0):
    arr = np.stack(lst, axis=0)

    return np.max(np.abs(np.diff(arr, axis=0))) <= threshold

print('all_equal(lst_eq)=', all_equal(lst_eq))
print('all_equal(lst_neq)=', all_equal(lst_neq))

output

all_equal(lst_eq)= True
all_equal(lst_neq)= False

Comments

1

one-liner solution:

arrays = [a, b, c]    
all([np.array_equal(a, b) for a, b in zip(arrays, arrays[1:])])

We test the equality of consecutive pairs of arrays

1 Comment

While this piece of code may answer the question, it is recommended to add some explaination on what it does.
0

This might work.

import numpy

x = np.random.rand(10)
arrays = [x for _ in range(10)]

print(np.allclose(arrays[:-1], arrays[1:]))  # True

arrays.append(np.random.rand(10))

print(np.allclose(arrays[:-1], arrays[1:]))  # False

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.