Reputation: 103
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
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
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
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
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
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