Как добавить элементы в двумерный массив, используя необычное индексирование Python? - PullRequest
0 голосов
/ 01 марта 2019

Я пишу программу на python и хочу максимально векторизовать ее.У меня есть следующие переменные

  1. 2D массив нулей E с формой (L,T).
  2. массив w с формой (N,) с произвольными значениями.
  3. массив index с формой (A,), значения которой являются целыми числами от 0 до N-1.Значения являются уникальными.
  4. массив labels с формой такой же, как w ((A,)), значения которой являются целыми числами от 0 до L-1. Значения не обязательно являются уникальными.
  5. Целое число t между 0 и T-1.

Мы хотим добавить значения w в индексах index в массив E в строках labels и столбце t.Я использовал следующий код:

E[labels,t] += w[index]

Но такой подход не дает желаемых результатов.Например,

import numpy as np

E = np.zeros([10,1])
w = np.arange(0,100)
index = np.array([1,3,4,12,80])
labels = np.array([0,0,5,5,2])
t = 0
E[labels,t] += w[index]

Дает

array([[ 3.],
   [ 0.],
   [80.],
   [ 0.],
   [ 0.],
   [12.],
   [ 0.],
   [ 0.],
   [ 0.],
   [ 0.]])

Но правильный ответ будет

array([[ 4.],
       [ 0.],
       [80.],
       [ 0.],
       [ 0.],
       [16.],
       [ 0.],
       [ 0.],
       [ 0.],
       [ 0.]])

Есть ли способ добиться такого поведения без использования цикла for?

Я понял, что могу использовать это: np.add.at(E,[labels,t],w[index]), но это дает мне это предупреждение:

FutureWarning: Using a non-tuple sequence for multidimensional indexing is deprecated; use `arr[tuple(seq)]` instead of `arr[seq]`. In the future this will be interpreted as an array index, `arr[np.array(seq)]`, which will result either in an error or a different result.

1 Ответ

0 голосов
/ 01 марта 2019

По аналогии с вопросом , вы можете использовать np.bincount () для достижения вашей цели:

import numpy as np
import time

E = np.zeros([10,1])
w = np.arange(0,100)
index = np.array([1,3,4,12,80])
labels = np.array([0,0,5,5,2])
t = 0

# --------- Using np.bincount()
start = time.perf_counter()
for _ in range(10000):
    E = np.zeros([10,1])
    values = w[index]
    result = np.bincount(labels, values, E.shape[0])
    E[:, t] += result
print("Bin count time: {}".format(time.perf_counter() - start))
print(E)


# --------- Using for loop
for _ in range(10000):
    E = np.zeros([10,1])
    for i, in_ in enumerate(index):
        E[labels[i], t] += w[in_]
print("For loop time: {}".format(time.perf_counter() - start))
print(E)

Дает:

Bin count time: 0.045003452
[[ 4.]
 [ 0.]
 [80.]
 [ 0.]
 [ 0.]
 [16.]
 [ 0.]
 [ 0.]
 [ 0.]
 [ 0.]]
For loop time: 0.09853353699999998
[[ 4.]
 [ 0.]
 [80.]
 [ 0.]
 [ 0.]
 [16.]
 [ 0.]
 [ 0.]
 [ 0.]
 [ 0.]]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...