【问题标题】:Stitching arrays together in numpy在numpy中将数组拼接在一起
【发布时间】:2019-10-25 04:58:39
【问题描述】:

有没有一种简单的方法可以在 numpy 中将数组拼接在一起,这样一个数组中的第一项与另一个数组中的第三项相加?例如:

a = np.array((1,2,3))
b = np.array((2,3,4))

在这种情况下,我希望结果为 (1,2,5,3,4)。我可以用 for 循环来做到这一点,但我想知道是否有一种简单的方法也可以使用 numpy 来做到这一点。谢谢!

【问题讨论】:

  • 您只想为ab 执行此操作,还是您有更多数组?
  • 快速解决方案:np.concatenate((a[:-1], [a[-1] + b[0]], b[1:]))
  • 我有不同数量的数组,我想将它们拼接在一起,这样它们的结果就会以这种方式相加
  • 数组是变长的吗?
  • 数组重叠部分的数字是否总是相同的?如果不是,您如何指定哪个“获胜”?

标签: python arrays numpy numpy-ndarray


【解决方案1】:

假设您只想对连续数组的最后一项和第一项求和:

def stitch(arrs, dtype=None):
    if len(arrs) < 2:
        raise ValueError("Not supported")
    res = np.empty(sum(x.size - 1 for x in arrs) + 1, dtype=dtype)
    idx = 0
    res[0] = arrs[0][0]
    for i in range(len(arrs) - 1):
        a, b = arrs[i], arrs[i + 1]
        off = a.size - 1
        res[idx+1:idx+off] = a[1:-1]
        res[idx+off] = a[-1] + b[0]
        idx += off
    res[idx+1:] = arrs[-1][1:]
    return res

与其他答案不同,这个答案避免了不必要的列表转换/复制和添加。 :) 请注意,对于足够小尺寸的数组,@Torben 的答案可能仍然更快。

【讨论】:

    【解决方案2】:

    解决方案

    对于每两个数组中的一对,您可以执行以下操作。

    np.hstack([a[:-1], np.array([a[-1], b[0]]).sum(), b[1:]])
    

    对于数组列表:

    我在这里使用的虚拟数据是使用此解决方案末尾(最底部)给出的代码创建的。为此,您只需要以下两个功能。

    def array_stitch(a, b):
        c = np.hstack([a[:-1], np.array([a[-1], b[0]]).sum(), b[1:]]) 
        return c
    
    def recursive_array_stitch(array_list):
        c = array_stitch(array_list[0], array_list[1])
        for e in array_list[2:]:
            c = array_stitch(c, e)
        return c
    
    recursive_array_stitch(array_list)
    

    输出

    array([ 4,  5,  6,  8,  2,  3,  8,  5,  9,  4,  5,  6,  8,  5,  4,  5,  6,
           10,  2])
    

    这里array_list 由以下给出:

    [array([4, 5, 6, 7]),
     array([1, 2, 3, 4]),
     array([4, 5, 6]),
     array([3, 4, 5, 6, 7]),
     array([1, 2]),
     array([3, 4, 5, 6, 7]),
     array([2]),
     array([1, 2])]
    

    详细解决方案

    仅适用于两个数组,如问题的问题陈述中所示。对于多个数组,这可以递归使用,这就是上面部分中所做的。

    import numpy as np
    
    a = np.array((1,2,3))
    b = np.array((2,3,4))
    c = np.hstack([a[:-1], np.array([a[-1], b[0]]).sum(), b[1:]]) 
    c
    

    输出

    array([1, 2, 5, 3, 4])
    

    如果你想要它作为一个元组:c.tuple() 会给你(1, 2, 5, 3, 4)

    对于数组列表

    请参阅开头的解决方案以获取数组列表。我将使用使用以下代码创建的数据。

    # Dummy Data
    np.random.seed = 43
    start, stop = np.random.randint(1,5,size=8), np.random.randint(3,9,size=8)
    array_list = [np.arange(k,k+3) if l<=k else np.arange(k,l) for k,l in zip(start, stop)]
    array_list
    

    输出

    [array([4, 5, 6, 7]),
     array([1, 2, 3, 4]),
     array([4, 5, 6]),
     array([3, 4, 5, 6, 7]),
     array([1, 2]),
     array([3, 4, 5, 6, 7]),
     array([2]),
     array([1, 2])]
    

    【讨论】:

    • 根据 OP 的评论:我有可变数量的数组numpy.hstack 很难概括
    • @Chris 感谢您的指出。将相应地更新解决方案。
    • @Chris Generalized 解决方案与numpy.hstack 和可变数量的数组一起发布。
    • @JesseBluestein 请考虑投票。感谢您选择它作为接受答案。
    【解决方案3】:

    我不认为有一个简单的方法,因为这似乎不是一个常见的操作。

    如果您有已知的输入列表,我建议您预先分配结果,然后将 inplace-addition 与移动切片一起使用:

    def stitch(list_of_arrays):
        final_size = sum(len(arr) for arr in list_of_arrays) - len(list_of_arrays) + 1
        out = np.zeros(final_size)
        ofs = 0
        for arr in list_of_arrays:
            out[ofs:ofs+len(arr)] += arr
            ofs += len(arr) - 1
        return out
    

    【讨论】:

      【解决方案4】:

      一种使用functools.reduce的方式:

      import numpy as np
      from functools import reduce
      
      def f(arr1, arr2):
          return [*arr1[:-1], arr1[-1] + arr2[0], *arr2[1:]]
      
      a = np.array((1,2,3))
      b = np.array((2,3,4))
      c = np.array((10,20,30))
      
      reduce(f, [a,b,c])
      

      输出:

      [1, 2, 5, 3, 14, 20, 30]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-03-19
        • 1970-01-01
        • 1970-01-01
        • 2011-08-25
        • 1970-01-01
        • 1970-01-01
        • 2012-01-11
        • 1970-01-01
        相关资源
        最近更新 更多