我确定numpy
中的这个很容易,但我找不到合适的方法。基本上我需要像outer()
这样的东西但是需要减法。这是我通过LC的工作代码:
import numpy as np
a = np.array(((1,2,3), (2,3,4), (3,4,5)))
b = np.array(((6,7,8), (6,3,1)))
print np.array([i-j for i in a for j in b])
输出:
[[-5 -5 -5]
[-5 -1 2]
[-4 -4 -4]
[-4 0 3]
[-3 -3 -3]
[-3 1 4]]
以下是发布的答案的速度比较。 a
有1000000个条目,b
有100个:
In [22]: %timeit np.array([i-j for i in a for j in b])
1 loops, best of 3: 12.3 s per loop
In [23]: %timeit np.repeat(a,b.shape[0],0)-np.tile(b,(a.shape[0],1))
10 loops, best of 3: 50.1 ms per loop
In [24]: %timeit (a[:,np.newaxis,:]-b).reshape(-1, 3)
10 loops, best of 3: 125 ms per loop
答案 0 :(得分:5)
你可以通过在减法之前重塑a
来利用广播,然后重新整形以获得所需的结果:
In [97]: (a[:,np.newaxis,:]-b).reshape(-1, 3)
Out[97]:
array([[-5, -5, -5],
[-5, -1, 2],
[-4, -4, -4],
[-4, 0, 3],
[-3, -3, -3],
[-3, 1, 4]])
说明:
In [101]: a.shape
Out[101]: (3, 3)
In [99]: a[:,np.newaxis,:].shape
Out[99]: (3, 1, 3)
In [100]: b.shape
Out[100]: (2, 3)
当NumPy评估a[:,np.newaxis,:]-b
时,它会在减法之前将a[:,np.newaxis,:]
和b
的形状广播到(3, 2, 3)
。粗略地说,第一轴和第二轴不相互作用。减法仅在第3轴发生。相对于第一和第二轴对每个位置执行减法。这就是NumPy相当于
for i in a for j in b
结果是
In [102]: a[:,np.newaxis,:]-b
Out[102]:
array([[[-5, -5, -5],
[-5, -1, 2]],
[[-4, -4, -4],
[-4, 0, 3]],
[[-3, -3, -3],
[-3, 1, 4]]])
In [103]: (a[:,np.newaxis,:]-b).shape
Out[103]: (3, 2, 3)
唯一要做的就是重塑结果,使其达到理想的形式。
答案 1 :(得分:3)
使用 np.repeat()和 np.tile()重复/平铺数组
import numpy as np
a = np.array(((1,2,3), (2,3,4), (3,4,5)))
b = np.array(((6,7,8), (6,3,1)))
c = np.repeat(a,b.shape[0],0)-np.tile(b,(a.shape[0],1))
print c
array([[-5, -5, -5],
[-5, -1, 2],
[-4, -4, -4],
[-4, 0, 3],
[-3, -3, -3],
[-3, 1, 4]])