我有一个for循环,我想用numpy进行矢量化。在下面的代码段中,R
,A
和done
是长度为num_rows
的numpy数组,而Q和Q1是大小为(num_rows, num_cols)
的矩阵。另外值得注意的是,A
的所有元素都在0
和num_cols - 1
之间,done
的所有元素都是0
或1
。我基本上想做与下面for-loop相同的事情,但是利用了numpy矢量化。
重要信息:
R
是一个长度为num_rows
的numpy数组。任意值A
是一个长度为num_rows
的numpy数组。值可以是0到num_cols - 1
done
是一个长度为num_rows
的numpy数组。值为0或1 Q
是一个形状为(num_rows, num_cols)
Q1
也是形状为(num_rows, num_cols)
这是循环:
y = np.zeros((num_rows, num_cols))
for i in range(num_rows):
r = R[i]
a = A[i]
q = Q[i]
adjustment = r
if not done[i]:
adjustment += (gamma*max(Q1[i]))
q[a] = adjustment
y[i, :] = q
我认为我已经进行了调整"以矢量化方式使用以下行,我只需要对Q
矩阵进行赋值并输出正确的y
矩阵。
这些是我用来矢量化第一部分的线条:
q_max_adjustments = np.multiply(gamma * Q1.max(1), done) # This would be numpy array of length num_rows
true_adjustments = R + q_max_adjustments # Same dimension numpy array
示例输入和输出将是
gamma = 0.99
R = numpy.array([1,2,0,3,2])
A = numpy.array([0,2,0,1,1])
done = numpy.array([0,1,0,0,1])
Q = numpy.array([[1,2,3],
[4,5,6],
[7,8,9],
[10,11,12],
[13,14,15]])
Q1 = numpy.array([[1,2,3],
[4,5,6],
[7,8,9],
[10,11,12],
[13,14,15]])
output y should be array([[ 3.97, 2. , 3. ],
[ 4. , 5. , 2. ],
[ 8.91, 8. , 9. ],
[10. , 14.88, 12. ],
[13. , 2. , 15. ]])
修改
所以我认为我使用稀疏矩阵作为掩码等一起攻击了一些有效的东西......但考虑到所需的步骤数量,似乎这可能并不是特别高效。有没有更有效的方法来实现同一目标?代码如下
q_max_adjustments = np.multiply(gamma * Q1.max(1), 1-done)
true_adjustments = R + q_max_adjustments
mask = np.full((num_rows, num_cols), False)
mask[np.arange(num_rows), A] = True
value_mask = np.multiply(np.vstack(true_adjustments), mask)
np.copyto(Q, value_mask, where=mask)
答案 0 :(得分:2)
您的矢量化解决方案具有所有正确的元素,但包含一些不必要的并发症。使用高级索引的简化版本将是:
>>> y = Q.astype(float)
>>> D, = np.where(1-done)
>>> y[np.arange(A.size), A] = R
>>> y[D, A[D]] += gamma * Q1[D].max(axis=1)
>>> y
array([[ 3.97, 2. , 3. ],
[ 4. , 5. , 2. ],
[ 8.91, 8. , 9. ],
[10. , 14.88, 12. ],
[13. , 2. , 15. ]]