numpy数组上的操作包含不同大小的行

时间:2016-08-11 10:49:20

标签: python arrays numpy

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

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命令不应该确保转换到数组吗?

7 个答案:

答案 0 :(得分:5)

这是一种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()展平数组,然后减去展平的数组,然后根据以前的形状重新整形。

答案 1 :(得分:1)

两个数组的维度不匹配,即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]])

答案 2 :(得分:1)

您可以尝试:

>>> 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]]

或者 第二种方法是使用地图

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 :(得分:0)

没有NumPy:

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

另请参阅this questionthis one

答案 4 :(得分:0)

自定义函数怎么样,例如:

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)

答案 5 :(得分:0)

您收到错误,因为您的代码试图从子列表中减去子列表,如果您想使其工作,您可以通过以下方式执行相同的操作:

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

答案 6 :(得分:0)

嵌套列表理解将完成这项工作:

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]])