我正在用python编写程序,并且希望对其进行向量化。我有以下变量
E
的零点(L,T)
的二维数组。w
的数组(N,)
。index
的(A,)
,其值是0
和N-1
之间的整数。这些值是唯一的。labels
,形状与w
((A,)
)相同,其值是介于0
和L-1
之间的整数。 这些值不一定是唯一的。 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.
答案 0 :(得分: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.]]