【问题标题】:How to efficiently multiply for every sub-array alone first dimension of a 3d np.array, Python 3如何有效地为每个子数组单独乘以 3d np.array,Python 3 的第一维
【发布时间】:2017-10-09 20:19:51
【问题描述】:

我有一个 3d np.array x,带有x.shape == (r, n, m)

这意味着单独的维度r,每个元素都是一个二维数组n-by-m。 对于这些二维数组中的每一个,我想将它乘以一个向量。

这是一个例子。

import bumpy as np
x = np.array([[[1, 2, 3, 4],
               [4, 5, 6, 7],
               [7, 8, 9, 10]],
              [[4, 5, 6, 7],
               [7, 8, 9, 10],
               [10, 11, 12, 13]],
              [[7, 8, 9, 10],
               [10, 11, 12, 13],
               [13, 14, 15, 16]]])

所以x.shape(r=3, n=3, m=4)。仅第一维就有三个二维数组

r1 = [[1, 2, 3, 4],
      [4, 5, 6, 7],
      [7, 8, 9, 10]]

r2 = [[4, 5, 6, 7],
      [7, 8, 9, 10],
      [10, 11, 12, 13]]

r3 = [[7, 8, 9, 10],
      [10, 11, 12, 13],
      [13, 14, 15, 16]]]

对于每个二维数组,我想做同样的操作:第一行乘以k**(n-1),第二行乘以k**(n-2),以此类推。最后一行乘以k**(n-n)

r1为例:

k = 0.9
n = 3
r1_operated = np.empty_like(r1)
r1_operated[0] = r1[0] * k**(n-1)  # n = 3, so (n-1) = 2
r1_operated[1] = r1[1] * k**(n-2)  # n = 3, so (n-2) = 1
r1_operated[1] = r1[2] * k**(n-n)  # n = 3, so (n-n) = 0

我上面写的很丑,如果rn 非常大,可能会很粗。

您知道编写此算法的任何优雅高效的方法吗?

我正在使用 Python3。谢谢!

【问题讨论】:

    标签: python-3.x numpy multidimensional-array


    【解决方案1】:

    利用numpy.broadcasting:

    x * (k ** np.arange(x.shape[1]-1, -1, -1))[:,None]
    

    x * (k ** np.arange(x.shape[1]-1, -1, -1))[:,None]
    
    #array([[[  0.81,   1.62,   2.43,   3.24],
    #        [  3.6 ,   4.5 ,   5.4 ,   6.3 ],
    #        [  7.  ,   8.  ,   9.  ,  10.  ]],
    
    #       [[  3.24,   4.05,   4.86,   5.67],
    #        [  6.3 ,   7.2 ,   8.1 ,   9.  ],
    #        [ 10.  ,  11.  ,  12.  ,  13.  ]],
    
    #       [[  5.67,   6.48,   7.29,   8.1 ],
    #        [  9.  ,   9.9 ,  10.8 ,  11.7 ],
    #        [ 13.  ,  14.  ,  15.  ,  16.  ]]])
    

    比较:

    def by_element(r):
        k = 0.9
        n = 3
        r1_operated = np.empty_like(r1, dtype=np.float)
        r1_operated[0] = r[0] * k**(n-1)  # n = 3, so (n-1) = 2
        r1_operated[1] = r[1] * k**(n-2)  # n = 3, so (n-2) = 1
        r1_operated[2] = r[2] * k**(n-n)
        return r1_operated
    
    by_element(x[0])
    #array([[  0.81,   1.62,   2.43,   3.24],
    #       [  3.6 ,   4.5 ,   5.4 ,   6.3 ],
    #       [  7.  ,   8.  ,   9.  ,  10.  ]])
    
    by_element(x[1])
    #array([[  3.24,   4.05,   4.86,   5.67],
    #       [  6.3 ,   7.2 ,   8.1 ,   9.  ],
    #       [ 10.  ,  11.  ,  12.  ,  13.  ]])
    
    by_element(x[2])
    #array([[  5.67,   6.48,   7.29,   8.1 ],
    #       [  9.  ,   9.9 ,  10.8 ,  11.7 ],
    #       [ 13.  ,  14.  ,  15.  ,  16.  ]])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-28
      • 1970-01-01
      • 2016-07-09
      • 2020-12-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多