1

I have a 5 by 10 array and I want to flip a bit if a random number is greater than 0.9. However, this only works for the first row of the array and it doesn't get to the second and subsequent row. I replaced the bits with 3 and 4 so i can easily see if the flipping occurs. I have been getting results that look like this.

[[3 1 1 1 4 1 3 1 0 1]
 [1 1 0 0 1 0 1 1 1 0]
 [1 0 1 0 1 0 1 1 1 1]
 [0 0 1 0 1 1 0 1 1 1]
 [0 1 1 0 0 0 0 1 1 1]]

Please help me figure out where I'm wrong.


from random import random
RM =  np.random.randint(0,2, size=(5,10))
print(RM)
for k in range(0, RM.shape[0]):
    for j in range(0, RM.shape[1]):
        A  = random()
        if A > 0.9:
            if RM[k,j] == 0:
                np.put(RM, [k,j], [3]) 
                print("k1",k)
                print("j1", j)
            else:
                np.put(RM, [k,j], [4])  
                print("k2", k)
        else: 
            continue

print(RM)

3 Answers 3

1

Looking at the documentation of np.put

numpy.put(a, ind, v, mode='raise')[source]
Replaces specified elements of an array with given values.

under Examples:

a = np.arange(5)
np.put(a, [0, 2], [-44, -55])
a
array([-44,   1, -55,   3,   4])

So, if you feed a list to the function, it replaces multiple values in the flattened array.

To make your loop work, simply assigning the values to the array should work:

from random import random
RM =  np.random.randint(0,2, size=(5,10))
print(RM)
for k in range(0, RM.shape[0]):
    for j in range(0, RM.shape[1]):
        A  = random()
        if A > 0.9:
            if RM[k,j] == 0:
                RM[k,j]=3 
                print("k1",k)
                print("j1", j)
            else:
                RM[k,j] =4  
                print("k2", k)
        else: 
            continue
Sign up to request clarification or add additional context in comments.

Comments

1

Most likely you don't need the iteration. The flips are independent, you can generate the probabilities at one go, and just flip:

np.random.seed(100)
RM =  np.random.randint(0,2, size=(5,10))

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

alpha = np.random.uniform(0,1,(5,10))
np.round(alpha,2)

array([[0.49, 0.4 , 0.35, 0.5 , 0.45, 0.09, 0.27, 0.94, 0.03, 0.04],
       [0.28, 0.58, 0.99, 0.99, 0.99, 0.11, 0.66, 0.52, 0.17, 0.94],
       [0.24, 1.  , 0.58, 0.18, 0.39, 0.19, 0.41, 0.59, 0.72, 0.49],
       [0.31, 0.58, 0.44, 0.36, 0.32, 0.21, 0.45, 0.49, 0.9 , 0.73],
       [0.77, 0.38, 0.34, 0.66, 0.71, 0.11, 0.13, 0.46, 0.16, 0.96]])

RM[alpha>0.9] = abs(1-RM[alpha>0.9])
RM

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

Comments

0

To iterate over a Numpy array, a convenient (and recommended) tool is nditer.

If you want to change values of the iterated array, op_flags=['readwrite'] should be passed.

To have access to the indices of the current element, in case of a multi-dimension array, flags=['multi_index'] should be passed.

Below you have example code, which also prints indices in each case the current element has been flipped.

To check how it operates, I added a printout of RM, both before and after the loop.

np.random.seed(0)
RM = np.random.randint(0, 2, size=(5, 10))
print('Before:')
print(RM, '\n')
with np.nditer(RM, op_flags=['readwrite'], flags=['multi_index']) as it:
    for x in it:
        A  = np.random.random()
        if A > 0.9:
            x[...] = 1 - x  # Flip
            print(f'Flip: <{it.multi_index}>,  {A:.3f}')
print('\nAfter:')
print(RM)

To get repeatable result, I added np.random.seed(0) (remove it in the target version).

With the above seeding, I got the following result:

Before:
[[0 1 1 0 1 1 1 1 1 1]
 [1 0 0 1 0 0 0 0 0 1]
 [0 1 1 0 0 1 1 1 1 0]
 [1 0 1 0 1 1 0 1 1 0]
 [0 1 0 1 1 1 1 1 0 1]] 

Flip: <(0, 2)>,  0.945
Flip: <(1, 3)>,  0.944
Flip: <(2, 7)>,  0.988
Flip: <(4, 5)>,  0.976
Flip: <(4, 7)>,  0.977

After:
[[0 1 0 0 1 1 1 1 1 1]
 [1 0 0 0 0 0 0 0 0 1]
 [0 1 1 0 0 1 1 0 1 0]
 [1 0 1 0 1 1 0 1 1 0]
 [0 1 0 1 1 0 1 0 0 1]]

Compare elements indicated as flipped, in "Before" and "After" sections, to confirm that the above code does its job. Check also that no other element has been changed.

A bit tricky element in the above code is x[...] = 1 - x. Note that 1 - x part reads the current value (so far it is OK). But if you attempted to save anything to x, writing x =, then you would break the link to the source array element. In this case x would point to the new value, but not to the current array element.

So in order not to break this link, just x[...] = notation is needed.

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.