Установить значение в двумерном массиве Numpy на основе суммы строк - PullRequest
0 голосов
/ 27 ноября 2018

Возможно ли это сделать с помощью Numpy и с хорошей производительностью?

Исходный двумерный массив:

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

Если сумма каждой строки меньше 4, установите последний элемент вкаждая строка в 1:

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

Разделите каждый элемент в каждой строке на сумму каждой строки и получите результат:

array([[0, 0.25, 0.25, 0.25, 0.25, 0],
   [0, 0, 0.5, 0, 0, 0.5],
   [0.5, 0, 0, 0, 0, 0.5]])

Ответы [ 3 ]

0 голосов
/ 27 ноября 2018

Я думаю, вам нужно:

x = np.array([[0, 1, 1, 1, 1, 0],
   [0, 0, 1, 0, 0, 0],
   [1, 0, 0, 0, 0, 1]])

x[:,-1][x.sum(axis=1) < 4] = 1
# array([[0, 1, 1, 1, 1, 0],
#   [0, 0, 1, 0, 0, 1],
#  [1, 0, 0, 0, 0, 1]])

print(x/x.sum(axis=1)[:,None])

Вывод:

array([[0.  , 0.25, 0.25, 0.25, 0.25, 0.  ],
       [0.  , 0.  , 0.5 , 0.  , 0.  , 0.5 ],
       [0.5 , 0.  , 0.  , 0.  , 0.  , 0.5 ]])
0 голосов
/ 27 ноября 2018

numpy.where также может быть полезно здесь, чтобы найти строки, соответствующие вашему условию :

import numpy as np
a = np.array([[0, 1, 1, 1, 1, 0],
              [0, 0, 1, 0, 0, 0],
              [1, 0, 0, 0, 0, 1]])

a[np.sum(a,axis=1) < 4, -1] = 1
a = a/a.sum(axis=1)[:,None]

print(a)

# Output 
# [[0.   0.25 0.25 0.25 0.25 0.  ]
#  [0.   0.   0.5  0.   0.   0.5 ]
#  [0.5  0.   0.   0.   0.   0.5 ]]

PS: отредактировано после @tel предлагаем:)

0 голосов
/ 27 ноября 2018

Вы можете сделать условное присваивание в одной строке с некоторым умным логическим индексированием:

arr = np.array([[0, 1, 1, 1, 1, 0],
                    [0, 0, 1, 0, 0, 0],
                    [1, 0, 0, 0, 0, 1]])

arr[arr.sum(axis=1) < 4, -1] = 1
print(arr)

Выход:

[[0 1 1 1 1 0]
 [0 0 1 0 0 1]
 [1 0 0 0 0 1]]

Затем вы можете разделить каждую строку на ее сумму следующим образом:

arr = arr / arr.sum(axis=1, keepdims=True)
print(arr)

Вывод:

[[0.   0.25 0.25 0.25 0.25 0.  ]
 [0.   0.   0.5  0.   0.   0.5 ]
 [0.5  0.   0.   0.   0.   0.5 ]]

Пояснение

Давайте присвоим массиву логических индексов arr.sum(axis=1) >= 4 имя boolix.boolix выглядит следующим образом:

[ True False False]

Если вы нарезаете arr на boolix, он вернет массив со всеми строками arr, для которых соответствующее значение в boolix равноTrue.Таким образом, результатом arr[boolix] является массив с 1 st и 2 ой строками arr:

[[0 0 1 0 0 0]
 [1 0 0 0 0 1]]

В приведенном выше коде arr был разрезан как arr[boolix, -1],Добавление второго индекса к срезу arr[anything, -1] заставляет срез содержать только последнее значение в каждой строке (т. Е. Значение в последнем столбце).Таким образом, arr[boolix, -1] вернет:

[0 1]

Поскольку этим слайсам также можно назначить, назначение 1 слайсу arr[boolix, -1] решит вашу проблему.

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