gocen
gocen

Reputation: 103

Element wise comparison between 2d arrays by if condition

I have two 2D numpy arrays a and b with size of 200*200 I want to element wise comparison of these two arrays with conditions:

if a[x][y] and b[x][y] is 0 print 0

if any of a[x][y] and b[x][y] is 0 print non-zero element

if a[x][y] and b[x][y] is non-zero print little element/ large element

I've tried np.all but it compares with only one condition

I want something like this C code:

for(i=0;i<200;i++)

  for(j=0:j<200;j++)


     if( a[i][j]==0 and b[i][j]==0)
       ....
       ....

After comparison I want to print results to another 2D array. How can I do it with python coding?

Upvotes: 0

Views: 1013

Answers (5)

Phuong D.
Phuong D.

Reputation: 46

You can also use numpy.vectorize:

def conditions(x, y):
    if (x == 0) & (y == 0):
        return 0
    elif (x != 0) & (y == 0):
        return x
    elif (x == 0) & (y!= 0):
        return y
    else:
        return x / y if x < y else y / x

v_conditions = np.vectorize(conditions)
c = v_conditions(a, b)

Upvotes: 1

some_name.py
some_name.py

Reputation: 827

depends on your application ofc but the nice thing with numpy would be that you dont have to loop (and therefore its much faster)

import numpy as np

np.random.seed(42)
a = np.random.randint(0,3,size=(5,5))
b = np.random.randint(0,3,size=(5,5))
print(a)
print(b)


where_a_eq_zero = a==0
where_b_eq_zero = b==0


# conditino: a and b is zero
con1 = where_a_eq_zero & where_b_eq_zero
print(con1)

# conditino: a or b is zero
con2 = np.logical_or(where_a_eq_zero,where_b_eq_zero)
print(con2)

# conditino: none of both is a zero element
con3 = ~where_a_eq_zero & ~where_b_eq_zero
print(con3)
# a
array([[2, 0, 2, 2, 0],
       [0, 2, 1, 2, 2],
       [2, 2, 0, 2, 1],
       [0, 1, 1, 1, 1],
       [0, 0, 1, 1, 0]])

# b
array([[0, 0, 2, 2, 2],
       [1, 2, 1, 1, 2],
       [1, 2, 2, 0, 2],
       [0, 2, 2, 0, 0],
       [2, 1, 0, 1, 1]])

# conditino: a and b is zero
array([[False,  True, False, False, False],
       [False, False, False, False, False],
       [False, False, False, False, False],
       [ True, False, False, False, False],
       [False, False, False, False, False]])

# conditino: a or b is zero
array([[ True,  True, False, False,  True],
       [ True, False, False, False, False],
       [False, False,  True,  True, False],
       [ True, False, False,  True,  True],
       [ True,  True,  True, False,  True]])

# conditino: none of both is a zero element
array([[False, False,  True,  True, False],
       [False,  True,  True,  True,  True],
       [ True,  True, False, False,  True],
       [False,  True,  True, False, False],
       [False, False, False,  True, False]])

now if you further want to use it (based on your comment) you can just use it like:

# fill up the array with np.nan because zero could be a possible 
# outcome and we can not differentiate if we missed that item or we wrote a 
# zero to this position. Later we can check if all np.nan´s are gone.
skor = np.full(a.shape,np.nan)

skor[con2] = -np.abs(a[con2]-b[con2])

my_min = np.minimum(a,b)
my_max = np.maximum(a,b)
skor[con3] = my_min[con3]/my_max[con3]

skor[con1] = 0

assert not np.any(skor==np.nan)
skor
>>> array([[-2. ,  0. ,  1. ,  1. , -2. ],
           [-1. ,  1. ,  1. ,  0.5,  1. ],
           [ 0.5,  1. , -2. , -2. ,  0.5],
           [ 0. ,  0.5,  0.5, -1. , -1. ],
           [-2. , -1. , -1. ,  1. , -1. ]])

Upvotes: 4

tevemadar
tevemadar

Reputation: 13195

I don't want to print conditions. I want to print scores to another array like this if a == 0 and b == 0: skor[i,j] = 0 elif a or b == 0: skor[i,j] = -abs(a-b) elif a != 0 and b != 0: skor[i,j] = min(a,b) / max(a,b)

You may want to add that comment to the question, especially as momentarily it says print non-zero element, without the negative sign.

I think -abs(0-0) may be zero enough already (though a negative one), so if differences are calculated at the beginning, one can simply correct the result where both players/teams have a non-zero score.

 import numpy
 a=numpy.random.randint(0,3,size=(5,5)) # stolen from @nahtanoj
 b=numpy.random.randint(0,3,size=(5,5))
 c=-abs(a-b).astype(float) # difference for starters
 abmin=numpy.minimum(a,b)
 abmax=numpy.maximum(a,b)
 recalc=abmin!=0           # where minimum is not zero, both players/teams scored some
 c[recalc]=abmin[recalc]/abmax[recalc]
 print(a)
 print(b)
 print(c)

Example output:

[[0 2 0 1 1]
 [2 1 2 2 0]
 [0 0 2 1 2]
 [2 1 2 0 1]
 [2 1 0 2 2]]
[[0 2 1 2 0]
 [2 1 2 2 2]
 [1 2 1 2 2]
 [1 0 2 0 2]
 [0 2 0 1 1]]
[[-0.   1.  -1.   0.5 -1. ]
 [ 1.   1.   1.   1.  -2. ]
 [-1.  -2.   0.5  0.5  1. ]
 [ 0.5 -1.   1.  -0.   0.5]
 [-2.   0.5 -0.   0.5  0.5]]

Upvotes: 0

Derek Eden
Derek Eden

Reputation: 4618

import itertools  

for x,y in itertools.product(range(a.shape[0]),range(a.shape[1])):
    if a[x,y] == 0 and b[x,y] == 0:
        print(0)
    elif a[x,y] or b[x,y] == 0:
        print('non-zero element')
    elif a[x,y] != 0  and b[x,y] != 0:
        print('little element')

iterools.product just provides way to do a nested loop in one line

Upvotes: 1

ozkulah
ozkulah

Reputation: 64

You can use same approach just like C code.

for i in range(len(a)):
      for j in range(len(a[i])):
        if a[i][j]==0 and b[i][j]==0
        ....

Upvotes: 0

Related Questions