【问题标题】:Efficiently compute product of all other elements in Numpy高效计算 Numpy 中所有其他元素的乘积
【发布时间】:2021-10-04 12:51:30
【问题描述】:

A 是一个二维矩阵。如何计算矩阵B,使得B 的每个元素都是A 同一行中所有其他条目的乘积?

例子:

A = np.array([[5, 0, 6],   # the input
              [3, 1, 9],
              [2, 0, 0]])

B = np.array([[0, 30, 0],  # the result
              [9, 27, 3],
              [0,  0, 0]])

天真的策略 (B = np.prod(A, axis=-1, keepdims=True) / A) 会遇到除零错误,不幸的是,这些零在程序的其他地方很重要,不能轻易地用微小的 epsilon 替换。

我已经尝试使用np.where 来解决这三种情况(没有零的行、有一个零的行、有多个零的行),但是尽管这可以防止输出中出现 NaN,但它仍然需要在让np.where 按元素进行挑选,这似乎需要大量代码和不必要的计算工作(并且在此过程中仍会产生 div-by-zero 警告)。

解决这个问题的最聪明、最快的方法是什么?

【问题讨论】:

    标签: numpy matrix numeric


    【解决方案1】:

    我找到了this answer,并受到它的启发,提出了以下高效的解决方案:

    def products_of_others(a, axes=None):
        if axes is None:
            axes = tuple(range(a.ndim))
        if isinstance(axes, int):
            axes = (axes,)
    
        # flatten the desired axes into one last dimension
        original_shape = a.shape
        other_axes = tuple([ax for ax in range(a.ndim) if ax not in axes])
        new_ax_order = other_axes + axes
        old_ax_order = np.argsort(new_ax_order)
        a = np.transpose(a, new_ax_order)
        a = np.reshape(a, [original_shape[ax] for ax in other_axes] + [np.prod([original_shape[ax] for ax in axes])])
    
        after = np.concatenate([a[..., 1:], np.ones_like(a[..., 0:1])], axis=-1)
        before = np.concatenate([np.ones_like(a[..., 0:1]), a[..., :-1]], axis=-1)
        after_prod = np.cumprod(after[..., ::-1], axis=-1)[..., ::-1]
        before_prod = np.cumprod(before, axis=-1)
    
        # undo the flattening
        out = np.reshape(after_prod * before_prod, [original_shape[ax] for ax in other_axes] + [original_shape[ax] for ax in axes])
        out = np.transpose(out, old_ax_order)
    
        return out
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-04-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-06
      • 1970-01-01
      • 2020-07-24
      • 2015-11-04
      相关资源
      最近更新 更多