Цикл по массиву numpy - PullRequest
       0

Цикл по массиву numpy

1 голос
/ 30 мая 2020

У меня есть массив 5 на 10, и я хочу немного перевернуть, если случайное число больше 0,9. Однако это работает только для первой строки массива и не попадает во вторую и последующие строки. Я заменил биты на 3 и 4, чтобы я мог легко увидеть, происходит ли переворот. Я получаю примерно такие результаты.

[[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]]

Помогите, пожалуйста, разобраться, в чем я ошибаюсь.


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 ]

1 голос
/ 30 мая 2020

Скорее всего итерация вам не нужна. Флипы независимы, вы можете сгенерировать вероятности с одним go и просто перевернуть:

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]])
1 голос
/ 30 мая 2020

Глядя на документацию np.put

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

в разделе Примеры:

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

Итак, если вы передаете в функцию список, она заменяет несколько значений в сглаженном массиве.

Чтобы ваш l oop работал, должно работать простое присвоение значений массиву:

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
0 голосов
/ 30 мая 2020

Чтобы перебрать массив Numpy, удобный (и рекомендуемый) инструмент - nditer .

Если вы хотите изменить значения повторяемого массива , op_flags = ['readwrite'] должно быть передано.

Чтобы иметь доступ к индексам текущего элемента, в случае многомерного массива , flags = ['multi_index'] должен быть передан.

Ниже приведен пример кода, который также печатает индексы в каждом случае, когда текущий элемент был перевернут.

Чтобы проверьте, как он работает, я добавил распечатку RM , как до, так и после l oop.

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)

Чтобы получить повторяемый результат, я добавил np.random.seed(0) (удалите его в целевой версии).

С указанным выше заполнением я получил следующий результат:

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]]

Сравните элементы, указанные как перевернутые, в разделах «До» и «После», чтобы подтвердить что приведенный выше код выполняет свою работу. Также убедитесь, что другие элементы не были изменены.

Немного сложный элемент в приведенном выше коде - x[...] = 1 - x. Обратите внимание, что часть 1 - x считывает текущее значение (пока все в порядке). Но если вы попытаетесь сохранить что-нибудь в x , написав x =, то вы разорвете ссылку на элемент исходного массива. В этом случае x будет указывать на новое значение, но не на текущий элемент массива.

Итак, чтобы не разрывать эту ссылку, просто x[...] = требуется обозначение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...