【问题标题】:How to add elements to a 2D array using python fancy indexing?如何使用 python 花式索引将元素添加到二维数组?
【发布时间】:2019-03-01 17:24:54
【问题描述】:

我正在用 python 编写一个程序,我想尽可能地对其进行矢量化。我有以下变量

  1. 二维零数组E,形状为(L,T)
  2. 数组w,形状为(N,),任意值。
  3. 数组index,形状为(A,),其值是介于0N-1 之间的整数。这些值是独一无二的。
  4. 数组labels,形状与w(A,))相同,其值为0L-1之间的整数。 这些值不一定是唯一的。
  5. 0T-1 之间的整数 t

我们希望将索引index 处的w 的值添加到数组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.

【问题讨论】:

  • 很抱歉,indices 是什么?我想你的意思是index..对吗??
  • 警告表明使用像np.add.at(E, (labels, t), w[index]) 这样的元组,而不是传递list

标签: python arrays numpy indexing


【解决方案1】:

从类似的question 中提取,您可以使用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.]]

【讨论】:

  • np.bincount 有一个限制,它的输入必须是非负整数。
  • 同意,但可以通过快速单线轻松解决,将负索引转换为正索引。权重不必是非负整数。
猜你喜欢
  • 1970-01-01
  • 2021-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-29
  • 1970-01-01
  • 2013-03-05
  • 2021-08-19
相关资源
最近更新 更多