简体   繁体   English

如何使用python花式索引向二维数组添加元素?

[英]How to add elements to a 2D array using python fancy indexing?

I am writing a program in python and I want to vectorize it as much as possible.我正在用 python 编写一个程序,我想尽可能地将它向量化。 I have the following variables我有以下变量

  1. 2D array of zeros E with shape (L,T) .具有形状(L,T)二维零点E数组。
  2. array w with shape (N,) with arbitrary values.具有任意值的形状(N,)数组w
  3. array index with shape (A,) whose values are integers between 0 and N-1 .形状为(A,)的数组index (A,)其值为0N-1之间的整数。 The values are unique.这些值是唯一的。
  4. array labels with a shape the same as w ( (A,) ), whose values are integers between 0 and L-1 .形状与w ( (A,) ) 相同的数组labels ,其值为0L-1之间的整数。 The values are not necessarily unique.这些值不一定是唯一的。
  5. Integer t between 0 and T-1 . 0T-1之间的整数t

We want to add the values of w at indices index to the array E at rows labels and column t .我们想将索引index处的w值添加到行labels和列t处的数组E中。 I used the following code:我使用了以下代码:

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

But this approach does not give desired results.但是这种方法并没有给出想要的结果。 For example,例如,

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]

Gives

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

But the correct answer would be但正确的答案是

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

Is there a way to achieve this behavior without using a for loop?有没有办法在不使用 for 循环的情况下实现这种行为?

I realized I can use this: np.add.at(E,[labels,t],w[index]) but it gives me this warning:我意识到我可以使用这个: 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.

Pulled from a similar question , you can use np.bincount() to achieve your goal:从一个类似的问题中提取,您可以使用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)

Gives:给出:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM