【问题标题】:handling arrays with missmatched sizes处理大小不匹配的数组
【发布时间】:2020-02-04 11:07:39
【问题描述】:

我想在 python 中创建一个函数,允许在两个不匹配的数组之间进行广播。我是 python 新手,我尝试了很多东西,比如 reshape 或 newaxis,但我无法让它工作。有人可以向我解释怎么做吗?对于任何维度,一个数组的大小应该是另一个数组的倍数,如下所示。

import numpy as np
arr = np.arange(12).reshape(4,3)
arr2 = np.arange(6).reshape(2,3)

【问题讨论】:

  • 你的函数究竟会做什么?
  • 请举例说明您要达到的目标。目前还不清楚你在问什么或你想做什么。

标签: python arrays numpy linear-algebra


【解决方案1】:

您可以使用numpy tile 重复数组。

对于这里的一个具体示例,您可以按如下方式添加两个数组:

out = arr + np.tile(arr2, (2, 1))
#Output:
array([[ 0,  2,  4],
       [ 6,  8, 10],
       [ 6,  8, 10],
       [12, 14, 16]])

对于更通用的函数,它会稍微复杂一些,但方法很简单:通过检查沿每个轴的最大值来确定输出数组的正确形状。然后单独使用瓷砖来实现所需的形状。

def broadcast_arr(arr1, arr2):
    ''' takes two arrays. 
    returns two arrays broadcasted to the maximum shape
    corresponding to the input array for elementwise operations if possible
    '''
    shape1 = arr1.shape
    shape2 = arr2.shape
    shape_out = max(len(shape1), len(shape2))
    temp = np.ones((2, shape_out), dtype='int')
    temp[0][-len(shape1):] = shape1
    temp[1][-len(shape2):] = shape2
    shape_out = temp.max(0)
    if (shape_out % temp).any():
        raise ValueError("incompatible arrays provided")
    out1 = np.tile(arr1, shape_out // temp[0])
    out2 = np.tile(arr2, shape_out // temp[1])
    return out1, out2

temp1, temp2 = broadcast_arr(arr, arr2)
out = temp1 + temp2
#Output:
array([[ 0,  2,  4],
       [ 6,  8, 10],
       [ 6,  8, 10],
       [12, 14, 16]])
out.shape #(4, 3)

【讨论】:

    【解决方案2】:

    也许numpy.tilenumpy.repeat 可以帮助您。 tile 将数组作为一个整体重复,repeat 在元素方面起作用:

    a3 = np.arange(3)               # array([0, 1, 2])
    a6t = np.tile(a, reps=2)        # array([0, 1, 2, 0, 1, 2])
    a6r = np.repeat(a, repeats=2)   # array([0, 0, 1, 1, 2, 2])
    

    通过这两种操作,您可以沿一个或多个轴重复您的数组以匹配另一个:

    import numpy as np
    arr = np.arange(12).reshape(4,3)
    arr2 = np.arange(6).reshape(2,3)
    
    arr2_t = np.tile(arr2, reps=(2, 1))
    # array([[0, 1, 2],
    #        [3, 4, 5],
    #        [0, 1, 2],
    #        [3, 4, 5]])
    arr2_r = np.repeat(arr2, repeats=2, axis=0)
    # array([[0, 1, 2],
    #        [0, 1, 2],
    #        [3, 4, 5],
    #        [3, 4, 5]])
    
    arr3 = arr - arr2_t
    arr4 = arr * arr2_r
    
    

    请注意这两个函数的调用签名略有不同。

    一般:

    • tile 使用 reps (tuple) 指定每个轴的(可能不同的)重复次数
    • repeat 使用 repeats 指定沿 axis (int) 的每个元素应重复的频率,repeats 将被广播以适应轴
      • np.repeat(a=range(3), repeats=3) # array([0, 0, 0, 1, 1, 1, 2, 2, 2])
      • np.repeat(a=range(4), repeats=range(4) # array([1, 2, 2, 3, 3, 3])

    【讨论】:

      猜你喜欢
      • 2021-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-11
      • 1970-01-01
      • 2015-10-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多