is there any pythonic way to remove for loop and if/else in the code below.
this code iterating over a NumPy array and check a condition and according to the condition change the value.
>>> import numpy as np >>> x=np.random.randint(100, size=(10,5)) >>> x array([[79, 50, 18, 55, 35], [46, 71, 46, 95, 52], [97, 37, 71, 2, 79], [80, 96, 60, 85, 72], [ 6, 52, 63, 86, 38], [35, 50, 13, 93, 54], [69, 21, 4, 40, 53], [83, 7, 30, 16, 78], [18, 34, 91, 67, 89], [82, 16, 16, 24, 80]]) >>> for i in range(x.shape[0]): for j in range(x.shape[1]): if x[i,j]>50: x[i,j]=0 elif x[i,j]<50: x[i,j]=1 >>> x array([[ 0, 50, 1, 0, 1], [ 1, 0, 1, 0, 0], [ 0, 1, 0, 1, 0], [ 0, 0, 0, 0, 0], [ 1, 0, 0, 0, 1], [ 1, 50, 1, 0, 0], [ 0, 1, 1, 1, 0], [ 0, 1, 1, 1, 0], [ 1, 1, 0, 0, 0], [ 0, 1, 1, 1, 0]])
I want to do same thing without loops and if statement. something like below dose not work, because of changes on the array:
>>> import numpy as np >>> x=np.random.randint(100, size=(10,5)) >>> x array([[ 2, 88, 27, 67, 29], [62, 44, 62, 87, 32], [80, 95, 31, 30, 33], [14, 41, 40, 95, 27], [53, 30, 35, 22, 98], [90, 39, 74, 28, 73], [10, 71, 0, 11, 37], [28, 25, 83, 24, 93], [30, 70, 15, 5, 79], [69, 43, 85, 68, 53]]) >>> x[x>50]=0 >>> x[x<50]=1 >>> x array([[1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1]])
UPDATE and what happend if there are more conditions like :
>>> import numpy as np >>> x=np.random.randint(100, size=(10,5)) >>> x array([[87, 99, 70, 32, 28], [38, 76, 89, 17, 34], [28, 1, 40, 34, 67], [45, 47, 69, 78, 89], [14, 81, 46, 71, 97], [39, 45, 36, 36, 25], [87, 28, 1, 46, 99], [27, 98, 37, 36, 84], [55, 2, 23, 29, 9], [34, 79, 49, 76, 48]]) >>> for i in range(x.shape[0]): for j in range(x.shape[1]): if x[i,j]>90: x[i,j]=9 elif x[i,j]>80: x[i,j]=8 elif x[i,j]>70: x[i,j]=7 elif x[i,j]>60: x[i,j]=6 elif x[i,j]>50: x[i,j]=5 elif x[i,j]>40: x[i,j]=4 else: x[i,j]=0 >>> x array([[8, 9, 6, 0, 0], [0, 7, 8, 0, 0], [0, 0, 0, 0, 6], [4, 4, 6, 7, 8], [0, 8, 4, 7, 9], [0, 4, 0, 0, 0], [8, 0, 0, 4, 9], [0, 9, 0, 0, 8], [5, 0, 0, 0, 0], [0, 7, 4, 7, 4]])
Approach #1 One approach -
keep_mask = x==50 out = np.where(x>50,0,1) out[keep_mask] = 50
Approach #2 Alternatively, for in-situ edit -
replace_mask = x!=50 x[replace_mask] = np.where(x>50,0,1)[replace_mask] # Or (x<=50).astype(int) in place of np.where(x>50,0,1)
Code-golf? If you actually want to play code-golf/one-liner -
(x<=50)+(x==50)*49
Approach #1
For a bit more generic case involving more if-elif parts, we could make use of np.searchsorted
-
out_x = np.where(x<=40,0, np.searchsorted([40,50,60,70,80,90], x)+3)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With