【问题标题】:Vectorizing a for loop with Numpy使用 Numpy 向量化 for 循环
【发布时间】:2018-08-26 04:16:46
【问题描述】:

我有一个 for 循环,我想用 numpy 进行矢量化。在下面的 sn-p 中,RAdone 是长度为 num_rows 的 numpy 数组,而 Q 和 Q1 是大小为 (num_rows, num_cols) 的矩阵。另外值得注意的是,A 的所有元素都在0num_cols - 1 之间,done 的所有元素要么是0 要么是1。我基本上想做与下面的 for 循环相同的事情,但要利用 numpy 向量化。

重要信息:

  • R 是一个长度为 num_rows 的 numpy 数组。任意值
  • A 是一个长度为 num_rows 的 numpy 数组。值可以是介于 0 和 num_cols - 1 之间的整数
  • done 是一个长度为 num_rows 的 numpy 数组。值为 0 或 1
  • Q 是一个二维 numpy 数组,形状为 (num_rows, num_cols)
  • Q1 也是一个二维 numpy 数组,形状为 (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)

【问题讨论】:

  • Qyq_max_adjustmentstrue_adjustments 的形状是什么?您能否为minimal reproducible example 提供示例输入true_adjustmentsq_max_adjustments 是否正确?
  • 添加了具体示例。是的,我相信true_adjustmentsq_max_adjustments 是正确的。
  • q_max_adjustmentstrue_adjustments 都不包含 y 中的数字。
  • 让我检查一下我的示例输出是否正确
  • 我的输出有问题。现在值应该是正确的。

标签: python numpy


【解决方案1】:

您的矢量化解决方案具有所有正确的元素,但包含一些不必要的复杂性。使用高级索引的简化版本是:

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

【讨论】:

    猜你喜欢
    • 2013-07-21
    • 2016-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-29
    • 1970-01-01
    相关资源
    最近更新 更多