【问题标题】:how to append a numpy matrix into an empty numpy array如何将一个 numpy 矩阵附加到一个空的 numpy 数组中
【发布时间】:2017-03-04 08:52:12
【问题描述】:

我想通过循环将一个 numpy 数组(矩阵)附加到一个数组中

data=[[2 2 2] [3 3 3]]
Weights=[[4 4 4] [4 4 4] [4 4 4]]
All=np.array([])  
for i in data:
    #i=[2 2 2 ]  #for example
    h=i*Weights         
    #h=[[8 8 8][8 8 8][8 8 8]] 
    All=np.concatenate((All,h),axis=0)                

我得到这个错误:

ValueError: all the input arrays must have same number of dimensions

我希望“All”变量为

[[8 8 8][8 8 8][8 8 8] [12 12 12][12 12 12][12 12 12]]

如何通过循环将“h”添加到“All”?

【问题讨论】:

    标签: python arrays numpy matrix append


    【解决方案1】:

    选项 1: 将您的初始 All 数组重新整形为 3 列,以便列数与 h 匹配:

    All=np.array([]).reshape((0,3))
    
    for i in data:
        h=i*Weights      
        All=np.concatenate((All,h))
    
    All
    #array([[  8.,   8.,   8.],
    #       [  8.,   8.,   8.],
    #       [  8.,   8.,   8.],
    #       [ 12.,  12.,  12.],
    #       [ 12.,  12.,  12.],
    #       [ 12.,  12.,  12.]])
    

    选项 2: 使用 if-else 语句处理初始空数组情况:

    All=np.array([])
    for i in data:
        h=i*Weights      
        if len(All) == 0:
            All = h
        else:
            All=np.concatenate((All,h))
    
    All
    #array([[ 8,  8,  8],
    #       [ 8,  8,  8],
    #       [ 8,  8,  8],
    #       [12, 12, 12],
    #       [12, 12, 12],
    #       [12, 12, 12]])
    

    选项 3: 使用itertools.product()

    import itertools
    np.array([i*j for i,j in itertools.product(data, Weights)])
    
    #array([[ 8,  8,  8],
    #       [ 8,  8,  8],
    #       [ 8,  8,  8],
    #       [12, 12, 12],
    #       [12, 12, 12],
    #       [12, 12, 12]])
    

    【讨论】:

    • 我尝试了第二个选项,效果很好,达到了目的。
    • 我会说我尝试了第三个选项,但它对我来说并不是很有效
    • 有趣。也许您的数据比您显示的更复杂,它在 python 2 和 python 3 中都为我提供了所需的输出。
    • 没错,我的数据比较复杂。我试图在问题中简化它
    【解决方案2】:

    Adam,只使用一对嵌套循环怎么样?我相信这段代码会做你想做的。

    import numpy as np
    data = ([2,2,2],[3,3,3])
    weights = ([4,4,4],[4,4,4],[4,4,4])
    
    output=np.array([])
    for each_array in data:
        for weight in weights:
                each_multiplication = np.multiply(each_array, weight)
                output = np.append(output,each_multiplication)
    
    print output
    

    np.multiply() 执行元素乘法而不是矩阵乘法。尽我所能从您的示例输入和输出中了解到,这就是您要完成的工作。

    【讨论】:

      【解决方案3】:

      这可能不是最好的解决方案,但它似乎有效。

      data = np.array([[2, 2, 2], [3, 3, 3]])
      Weights = np.array([[4, 4, 4], [4, 4, 4], [4, 4, 4]])
      All = []
      
      for i in data:
          for j in Weights:
              h = i * j
              All.append(h)
      
      All = np.array(All)
      

      我想说这不是最好的解决方案,因为它将结果附加到列表中,最后将列表转换为 numpy 数组,但它适用于小型应用程序。我的意思是,如果您必须进行这样的繁重计算,我会考虑寻找另一种方法。无论如何,使用这种方法,您不必考虑浮点数的数字转换。希望这可以帮助。

      【讨论】:

      • 这是一种在需要循环时广泛使用的构造数组的方法。
      • 是的,我同意。我的意思是,如果您必须将其仅用于一些小型计算,我认为它可以做得很好,但它比仅使用 numpy 慢,并且如果数组很长,肯定要避免将数组附加到每次迭代中。跨度>
      【解决方案4】:

      使用循环构造数组的一种首选方法是收集列表中的值,并在最后执行一次concatenate

      In [1025]: data
      Out[1025]: 
      array([[2, 2, 2],
             [3, 3, 3]])
      In [1026]: Weights
      Out[1026]: 
      array([[4, 4, 4],
             [4, 4, 4],
             [4, 4, 4]])
      

      追加到列表比重复concatenate快得多;此外,它还避免了“空”数组形状问题:

      In [1027]: alist=[]
      In [1028]: for row in data:
            ...:     alist.append(row*Weights)
      In [1029]: alist
      Out[1029]: 
      [array([[8, 8, 8],
              [8, 8, 8],
              [8, 8, 8]]), array([[12, 12, 12],
              [12, 12, 12],
              [12, 12, 12]])]
      
      In [1031]: np.concatenate(alist,axis=0)
      Out[1031]: 
      array([[ 8,  8,  8],
             [ 8,  8,  8],
             [ 8,  8,  8],
             [12, 12, 12],
             [12, 12, 12],
             [12, 12, 12]])
      

      您还可以使用np.arraynp.stack 在新维度上加入数组:

      In [1032]: np.array(alist)
      Out[1032]: 
      array([[[ 8,  8,  8],
              [ 8,  8,  8],
              [ 8,  8,  8]],
      
             [[12, 12, 12],
              [12, 12, 12],
              [12, 12, 12]]])
      In [1033]: _.shape
      Out[1033]: (2, 3, 3)
      

      我可以用一个简单的广播乘法构建这个 3d 版本 - 没有循环

      In [1034]: data[:,None,:]*Weights[None,:,:]
      Out[1034]: 
      array([[[ 8,  8,  8],
              [ 8,  8,  8],
              [ 8,  8,  8]],
      
             [[12, 12, 12],
              [12, 12, 12],
              [12, 12, 12]]])
      

      添加.reshape(-1,3) 以获得 (6,3) 版本。

      np.repeat(data,3,axis=0)*np.tile(Weights,[2,1]) 还生成所需的 6x3 数组。

      【讨论】:

        猜你喜欢
        • 2016-02-29
        • 2015-10-06
        • 2017-07-22
        • 2021-10-25
        • 1970-01-01
        • 2010-10-08
        相关资源
        最近更新 更多