【问题标题】:Operation on numpy arrays contain rows with different size对 numpy 数组的操作包含不同大小的行
【发布时间】:2016-08-11 10:49:20
【问题描述】:

我有两个列表,如下所示:

a= [[1,2,3,4], [2,3,4,5],[3,4,5,6,7]], b= [[5,6,7,8], [9,1,2,3], [4,5,6,7,8]]

我想逐个元素地从其他元素中减去这样的输出:

a-b= [[-4,-4,-4,-4],[7,2,2,2],[-1,-1,-1,-1,-1]]

为此,我将ab 中的每一个都转换为数组并减去我使用的数组:

np.array(a)-np.array(b)

输出只是给了我错误:

不支持的操作数类型:'list' 和 'list'

我做错了什么? np.array命令不应该确保转换为数组吗?

【问题讨论】:

标签: python arrays numpy


【解决方案1】:

这是一种 Numpythonic 方式:

>>> y = map(len, a)  
>>> a = np.hstack(np.array(a))
>>> b = np.hstack(np.array(b))
>>> np.split(a-b, np.cumsum(y))
[array([-4, -4, -4, -4]), array([-7,  2,  2,  2]), array([-1, -1, -1, -1, -1]), array([], dtype=float64)]
>>> 

由于您无法减去具有不同形状的数组,您可以使用 np.hstack() 展平您的数组,然后减去您展平的数组,然后根据之前的形状重新整形。

【讨论】:

    【解决方案2】:

    你可以试试:

    >>> a= [[1,2,3,4], [2,3,4,5],[3,4,5,6,7]]
    >>> b= [[5,6,7,8], [9,1,2,3], [4,5,6,7,8]]
    >>> 
    >>> c =[]
    >>> for i in range(len(a)):
        c.append([A - B for A, B in zip(a[i], b[i])])
    
    
    >>> print c
    [[-4, -4, -4, -4], [-7, 2, 2, 2], [-1, -1, -1, -1, -1]]
    

    或者 第二种方法是使用 ma​​p

    from operator import sub
    a= [[1,2,3,4], [2,3,4,5],[3,4,5,6,7]]
    b= [[5,6,7,8], [9,1,2,3], [4,5,6,7,8]]
    c =[]
    for i in range(len(a)):
        c.append(map(sub, a[i], b[i]))  
    print c
    [[-4, -4, -4, -4], [-7, 2, 2, 2], [-1, -1, -1, -1, -1]]
    

    【讨论】:

      【解决方案3】:

      两个数组的维度不匹配,即a 的前两个子列表有 4 个元素,但第三个有 5 个元素,b 也是如此。如果您将列表转换为numpy arraysnumpy 会默默地为您提供如下内容:

      In [346]: aa = np.array(a)
      In [347]: bb = np.array(b)
      In [348]: aa
      Out[348]: array([[1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6, 7]], dtype=object)
      In [349]: bb
      Out[349]: array([[5, 6, 7, 8], [9, 1, 2, 3], [4, 5, 6, 7, 8]], dtype=object)
      

      您需要确保所有子列表的元素数量相同,然后您的代码才能正常工作:

      In [350]: a = [[1,2,3,4], [2,3,4,5],[3,4,5,6]]; b = [[5,6,7,8], [9,1,2,3], [4,5,6,7]] # I removed the last element of third sublist in a and b
      In [351]: np.array(a) - np.array(b)
      Out[351]: 
      array([[-4, -4, -4, -4],
             [-7,  2,  2,  2],
             [-1, -1, -1, -1]])
      

      【讨论】:

      • 谢谢,这已经很有帮助了。不幸的是,这就是我的数据的样子.. 没有可以处理这样的列表的例程吗?
      • 你需要手动处理这个问题,例如,如果你想为你的用例使用numpy,可以用 0 填充较短的子列表。
      【解决方案4】:

      没有 NumPy:

      result = []
      for (m, n) in (zip(a, b)):
          result.append([i - j for i, j in zip(m, n)])
      

      另请参阅 this questionthis one

      【讨论】:

        【解决方案5】:

        自定义函数如:

        import numpy as np
        
        a = [[1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6, 7]]
        b = [[5, 6, 7, 8], [9, 1, 2, 3], [4, 5, 6, 7, 8]]
        
        
        def np_substract(l1, l2):
            return np.array([np.array(l1[i]) - np.array(l2[i]) for i in range(len(l1))])
        
        print np_substract(a, b)
        

        【讨论】:

          【解决方案6】:

          你得到了错误,因为你的代码试图从子列表中减去子列表,如果你想让它工作,你可以通过以下方式做同样的事情:

          import numpy as np
          a= [[1,2,3,4], [2,3,4,5],[3,4,5,6,7]]
          b= [[5,6,7,8], [9,1,2,3], [4,5,6,7,8]]
          
          #You can apply different condition here, like (if (len(a) == len(b)), then only run the following code    
          for each in range(len(a)):
              list = np.array(a[each])-np.array(b[each])
              #for converting the output array in to list
              subList[each] = list.tolist()
          
          print subList
          

          【讨论】:

            【解决方案7】:

            嵌套列表推导可以完成这项工作:

            In [102]: [[i2-j2 for i2,j2 in zip(i1,j1)] for i1,j1 in zip(a,b)] 
            Out[102]: [[-4, -4, -4, -4], [-7, 2, 2, 2], [-1, -1, -1, -1, -1]]
            

            np.array(a)-np.array(b) 的问题在于子列表的长度不同,因此生成的数组是对象类型 - 列表数组

            In [104]: np.array(a)
            Out[104]: array([[1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6, 7]], dtype=object)
            

            减法可以很好地迭代外部数组,但是在从另一个子列表中减去一个子列表时遇到问题 - 因此出现错误消息。

            如果我将输入数组设为数组,则减法将起作用

            In [106]: np.array([np.array(a1) for a1 in a])
            Out[106]: array([array([1, 2, 3, 4]), array([2, 3, 4, 5]), array([3, 4, 5, 6, 7])], dtype=object)
            
            In [107]: aa=np.array([np.array(a1) for a1 in a])   
            In [108]: bb=np.array([np.array(a1) for a1 in b])
            
            In [109]: aa-bb
            Out[109]: 
            array([array([-4, -4, -4, -4]), 
                   array([-7,  2,  2,  2]),
                   array([-1, -1, -1, -1, -1])], dtype=object)
            

            您无法计算对对象 dtype 数组起作用的数组操作。但在这种情况下,subtraction 是为子数组定义的,因此它可以处理嵌套。

            另一种嵌套方法是使用np.subtract。这是-ufunc 版本,并将根据需要将np.asarray 应用于其输入:

            In [103]: [np.subtract(i1,j1) for i1,j1 in zip(a,b)]
            Out[103]: [array([-4, -4, -4, -4]), array([-7,  2,  2,  2]), array([-1, -1, -1, -1, -1])]
            

            请注意,这些数组计算返回数组或数组列表。将内部数组转回列表需要迭代。

            如果您从列表开始,转换为数组通常不会节省时间。数组计算可以更快,但这并不能弥补首先创建数组的开销。

            如果我将输入填充为相等的长度,那么简单的数组减法就会起作用,创建一个二维数组。

            In [116]: ao= [[1,2,3,4,0], [2,3,4,5,0],[3,4,5,6,7]]; bo= [[5,6,7,8,0], [9,1,2,3,0], [4,5,6,7,8]]
            
            In [117]: np.array(ao)-np.array(bo)
            Out[117]: 
            array([[-4, -4, -4, -4,  0],
                   [-7,  2,  2,  2,  0],
                   [-1, -1, -1, -1, -1]])
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2018-10-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-03-24
              相关资源
              最近更新 更多