如何有效地将操作符应用于两个数组的笛卡尔积?

Cla*_*diu 5 python arrays performance numpy

我有a = array([1, 2, 3, 4, 5])b = array([10, 20, 30, 40, 50]).我想要:

array([[ -9, -19, -29, -39, -49],
       [ -8, -18, -28, -38, -48],
       [ -7, -17, -27, -37, -47],
       [ -6, -16, -26, -36, -46],
       [ -5, -15, -25, -35, -45]])
Run Code Online (Sandbox Code Playgroud)

最有效的方法是什么?我有

np.transpose([a]) - np.tile(b, (len(a), 1))
Run Code Online (Sandbox Code Playgroud)

但是我想知道是否有更高效的方法,如果a非常大,这不需要复制b太多(反之亦然).

unu*_*tbu 10

一些NumPy的功能,如np.subtract,np.add,np.multiply,np.divide,np.logical_and,np.bitwise_and,等具有可以被用来创建的"乘法表"等效"外"的方法:

In [76]: np.subtract.outer(a, b)
Out[76]: 
array([[ -9, -19, -29, -39, -49],
       [ -8, -18, -28, -38, -48],
       [ -7, -17, -27, -37, -47],
       [ -6, -16, -26, -36, -46],
       [ -5, -15, -25, -35, -45]])
Run Code Online (Sandbox Code Playgroud)

或者,使用广播:

In [96]: a[:, None] - b
Out[96]: 
array([[ -9, -19, -29, -39, -49],
       [ -8, -18, -28, -38, -48],
       [ -7, -17, -27, -37, -47],
       [ -6, -16, -26, -36, -46],
       [ -5, -15, -25, -35, -45]])
Run Code Online (Sandbox Code Playgroud)

两者的表现大致相同:

In [98]: a = np.tile(a, 1000)

In [99]: b = np.tile(b, 1000)

In [100]: %timeit a[:, None] - b
10 loops, best of 3: 88.3 ms per loop

In [101]: %timeit np.subtract.outer(a, b)
10 loops, best of 3: 87.8 ms per loop

In [102]: %timeit np.transpose([a]) - np.tile(b, (len(a), 1))
10 loops, best of 3: 120 ms per loop
Run Code Online (Sandbox Code Playgroud)