27
A = np.array([[0.94366988, 0.86095311, 0.88896715, 0.93630641, 0.74075403, 0.52849619
                  , 0.03094677, 0.85707681, 0.88457925, 0.67279696, 0.26601085, 0.4823794
                  , 0.74741157, 0.78575729, 0.00978911, 0.9203284, 0.02453695, 0.84884703
                  , 0.2050248, 0.03703224, 0.92931392, 0.11930532, 0.01411064, 0.7832698
                  , 0.58188015, 0.66897565, 0.75119007, 0.01323558, 0.03402649, 0.99735115
                  , 0.21031727, 0.78123225, 0.6815842, 0.46647604, 0.66323375, 0.03424828
                  , 0.08031627, 0.76570656, 0.34760863, 0.06177743, 0.6987531, 0.4106426
                  , 0.6648871, 0.02776868, 0.93053125, 0.46395717, 0.23971605, 0.9771735
                  , 0.66202407, 0.10482388]])

Convert the entries of a into 0 (if activation <= 0.5) or 1 (if activation > 0.5)

for i in range(A.shape[1]):
if A[i]>0.5:
    Y_prediction[i] = 1
else:
    Y_prediction[i] = 0

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

And how to use vectorize this thx

chrki
  • 6,143
  • 6
  • 35
  • 55
Ryan Wang
  • 271
  • 1
  • 3
  • 5
  • 1
    Does this answer your question? [Replacing Numpy elements if condition is met](https://stackoverflow.com/questions/19766757/replacing-numpy-elements-if-condition-is-met) – Georgy May 06 '20 at 13:57

7 Answers7

70

I think you need vectorized function np.where:

B = np.where(A > 0.5, 1, 0)
print (B)
[[1 1 1 1 1 1 0 1 1 1 0 0 1 1 0 1 0 1 0 0 1 0 0 1 1 1 1 0 0 1 0 1 1 0 1 0 0
  1 0 0 1 0 1 0 1 0 0 1 1 0]]

B = np.where(A <= 0.5, 0, 1)
print (B)
[[1 1 1 1 1 1 0 1 1 1 0 0 1 1 0 1 0 1 0 0 1 0 0 1 1 1 1 0 0 1 0 1 1 0 1 0 0
  1 0 0 1 0 1 0 1 0 0 1 1 0]]

But better is holdenweb solution if need convert to 0 and 1 only.

np.where is better if need convert to another scalars like 5 and 10 or a and b:

C = np.where(A > 0.5, 5, 10)
print (C)
[[ 5  5  5  5  5  5 10  5  5  5 10 10  5  5 10  5 10  5 10 10  5 10 10  5
   5  5  5 10 10  5 10  5  5 10  5 10 10  5 10 10  5 10  5 10  5 10 10  5
   5 10]]

D = np.where(A > 0.5, 'a', 'b')
print (D)
[['a' 'a' 'a' 'a' 'a' 'a' 'b' 'a' 'a' 'a' 'b' 'b' 'a' 'a' 'b' 'a' 'b' 'a'
  'b' 'b' 'a' 'b' 'b' 'a' 'a' 'a' 'a' 'b' 'b' 'a' 'b' 'a' 'a' 'b' 'a' 'b'
  'b' 'a' 'b' 'b' 'a' 'b' 'a' 'b' 'a' 'b' 'b' 'a' 'a' 'b']]

Timings:

np.random.seed(223)
A = np.random.rand(1,1000000)

#jez
In [64]: %timeit np.where(A > 0.5, 1, 0)
100 loops, best of 3: 7.58 ms per loop

#holdenweb
In [65]: %timeit (A > 0.5).astype(int)
100 loops, best of 3: 3.47 ms per loop

#stamaimer
In [66]: %timeit element_wise_round(A)
1 loop, best of 3: 318 ms per loop
jezrael
  • 822,522
  • 95
  • 1,334
  • 1,252
  • 4
    Good answer. `np.where` is my goto method for this. I prefer it over broadcasting to bools and converting to int, it's just more readable imo and applicable to other scalars and datatypes as you show. – nluigi Aug 12 '17 at 10:12
34

Standard numpy broadcasting can be used to compare each element with a scalar value, yielding a Boolean for each element. The ndarray.astype method then converts the True values to 1 and the False values to zero.

In [16]: (A > 0.5).astype(int)
Out[16]:
array([[1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0,
        0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0,
        1, 0, 0, 1, 1, 0]])
holdenweb
  • 33,305
  • 7
  • 57
  • 77
  • Doesn't seem to work. – Pyromonk Feb 12 '22 at 21:48
  • I assure you it does. Just checked with Python 3.9 and numpy 1.21.2. Not a terribly information-packed bug report, so I regret I'm unable to help further. – holdenweb Feb 13 '22 at 09:20
  • While checking I also checked the timing, and this method appears (on my computer!) to run about twice as fast as the most-upvoted answer. Not that speed is everything. – holdenweb Feb 13 '22 at 09:32
  • I've checked it both within my local Python install (also running 3.9) and [here](https://pynative.com/online-python-code-editor-to-execute-python-code/), and it didn't work on a numpy array for me. – Pyromonk Feb 13 '22 at 10:41
  • Again, I have no information that might help me to help you solve my problem. This is like "Help. My car is broken. Tell me what I need to do to fix it." I used the numpy array given in the question. I'm sure there are a million things it wouldn't work on, but none of them will be numpy arrays of real numbers. – holdenweb Feb 14 '22 at 15:56
3
np.random.seed(223)
A = np.random.rand(1000000)
A = [0 if i <=0.5 else 1 for i in A]
Tkanno
  • 656
  • 6
  • 14
  • Thx!can you tell me how to implement use for loop? – Ryan Wang Aug 12 '17 at 09:35
  • this is a list comprehension, which is much faster than using for loops in python. You don't need to loop to get the result. @jezrael 's answer is also a good method. – Tkanno Aug 12 '17 at 09:39
  • @Tkanno - I cannot add your solution for timeit, because `ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()` :( – jezrael Aug 12 '17 at 09:54
  • @jezrael that's because you've declared the array A shape (1,1000000). my method works on a flattened array, another limitation. if you flatten A you can timeit on my method. – Tkanno Aug 13 '17 at 11:36
  • @Tkanno - I try set input by data similar OP. But in my opinion here list comprehension is slowiest, because not vectorized. Is possible update your solution working with A? Then I can add timings too (if want) – jezrael Aug 13 '17 at 11:40
2

The problem with your code is the dimension of A[i] in your code. A is initialised as matrix[1,n] (1 row and n columns - you have double [[]] brackets in np.array([[]])), so you reference of type A[i] actually means "the whole i'th row, or an array(n) in this case). I'm quite new to python and numpy, but to access individual cells and set each to 1 or 0 could be coded this way (of course, only if you are forced to use FOR loops here):

 for i in range(A.shape[1]):
 if A[0,i]>0.5:
    Y_prediction[0,i] = 1
 else:
    Y_prediction[0,i] = 0

But,definitely, the best solution, as others described above, is to avoid for loop.

1

this may solve your issue

a=1
b=0
predict=list()
for i in A:
    if i>0.5:
        predict.append(a)
    else:
        predict.append(b)
print(predict)

we first assign value a to 0 and b to 1 but you can directly use 1 and 0 on append function 'A' contains the list in form of probability from which we assign the new list name predict and after comparing each items in list we put value into list by using append methord predict list contain your ans

0

You can make the built-in round function element wise use np.vectorize.

import numpy as np

element_wise_round = np.vectorize(round, otypes=[np.int])

print element_wise_round(A)
stamaimer
  • 6,227
  • 5
  • 34
  • 55
0
A1=A-0.5
A2=np.sign(A1)

Now you have 1 and -1. If you do not have 0 in the original array, you can convert the -1 to 0 to have only 1 and 0 array:

indices = A2 == -1
A2[indices] = 0

The result:

A2

array([[1., 1., 1., 1., 1., 1., 0., 1., 1., 1., 0., 0., 1., 1., 0., 1., 0., 1., 0., 0., 1., 0., 0., 1., 1., 1., 1., 0., 0., 1., 0., 1., 1., 0., 1., 0., 0., 1., 0., 0., 1., 0., 1., 0., 1., 0., 0., 1., 1., 0.]])

Farid
  • 33
  • 9