具有Numpy或TensorFlow的多个2D矩阵的高效轴方向笛卡尔积

时间:2017-06-02 07:45:36

标签: numpy product cartesian

首先,我认为我想要实现的是某种类型的笛卡尔积,但只是元素式的,仅在列中。

我想做的是,如果您有多个尺寸为[(N,D1),(N,D2),(N,D3)...(N,Dn)的< / p> 因此,结果是跨越轴= 1的组合产品,使得最终结果将具有形状(N,D),其中D = D1 * D2 * D3 * ... Dn

e.g。

A = np.array([[1,2],
              [3,4]])
B = np.array([[10,20,30],
              [5,6,7]])

cartesian_product( [A,B], axis=1 )
>> np.array([[ 1*10, 1*20, 1*30, 2*10, 2*20, 2*30 ]
             [ 3*5,  3*6,  3*7,  4*5,  4*6,  4*7  ]])

可扩展到cartesian_product([A,B,C,D ...],轴= 1)

e.g。

A = np.array([[1,2],
              [3,4]])
B = np.array([[10,20],
              [5,6]])
C = np.array([[50, 0],
              [60, 8]])
cartesian_product( [A,B,C], axis=1 )
>> np.array([[ 1*10*50, 1*10*0, 1*20*50, 1*20*0, 2*10*50, 2*10*0, 2*20*50, 2*20*0] 
             [ 3*5*60,  3*5*8,  3*6*60,  3*6*8,  4*5*60,  4*5*8,  4*6*60,  4*6*8]])

我有一个工作解决方案,基本上创建一个空(N,D)矩阵,然后为所提供列表中的每个矩阵的嵌套for循环中的每列广播矢量列产品。一旦阵列变大,显然很可怕!

是否存在numpy或tensorflow中的现有解决方案?可能是一个可以高效并行化的(一个张量流解决方案会很精彩,但是一个numpy就可以了,只要矢量逻辑很清晰,那么它就不应该很难得到一个等价的产品)

我不确定是否需要使用einsum,tensordot,meshgrid或其中某些组合才能实现此目的。我有一个解决方案,但仅适用于来自https://stackoverflow.com/a/11146645/2123721的单维向量,即使该解决方案适用于任意维度数组(这似乎意味着向量)。有了那个,我可以做一个.prod(axis = 1),但这只对矢量有效。

谢谢!

1 个答案:

答案 0 :(得分:1)

这是一种以累积的方式迭代地执行此操作的方法,在从数组列表中扩展每对的维度后,使用broadcasting进行元素的累加 -

L = [A,B,C]  # list of arrays
n = L[0].shape[0]
out = (L[1][:,None]*L[0][:,:,None]).reshape(n,-1)
for i in L[2:]:
    out = (i[:,None]*out[:,:,None]).reshape(n,-1)