带有Numpy或TensorFlow的多个2D矩阵的高效轴向笛卡尔积 [英] Efficient axis-wise cartesian product of multiple 2D matrices with Numpy or TensorFlow
问题描述
因此,首先,我认为我要实现的是某种笛卡尔积,但仅限于元素,仅跨列.
So first off, I think what I'm trying to achieve is some sort of Cartesian product but elementwise, across the columns only.
如果您有多个大小为[(N,D1),(N,D2),(N,D3)...(N,Dn)]的2D数组,我想做的是
What I'm trying to do is, if you have multiple 2D arrays of size [ (N,D1), (N,D2), (N,D3)...(N,Dn) ]
因此,结果将是跨轴= 1的组合乘积,这样最终结果将为(N,D)形状,其中D = D1 * D2 * D3 * ... Dn
The result is thus to be a combinatorial product across axis=1 such that the final result will then be of shape (N, D) where D=D1*D2*D3*...Dn
例如
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 ]])
并可扩展到笛卡尔乘积([A,B,C,D ...],轴= 1)
and extendable to cartesian_product([A,B,C,D...], axis=1)
例如
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)矩阵,然后为提供的列表中的每个矩阵嵌套嵌套循环的每一列广播一个矢量列乘积.一旦数组变大,显然很可怕!
I have a working solution that essentially creates an empty (N,D) matrix and then broadcasting a vector columnwise product for each column within nested for loops for each matrix in the provided list. Clearly is horrible once the arrays get larger!
在numpy或tensorflow中是否存在为此的现有解决方案?可能是有效可参数化的(张量流解决方案会很不错,但可以使用numpy,并且只要向量逻辑清晰即可,则不难将tf等效)
Is there an existing solution within numpy or tensorflow for this? Potentially one that is efficiently paralleizable (A tensorflow solution would be wonderful but a numpy is ok and as long as the vector logic is clear then it shouldn't be hard to make a tf equivalent)
我不确定是否需要使用einsum,tensordot,meshgrid或它们的某种组合来实现此目的.我有一个解决方案,但仅适用于 https://stackoverflow.com/a/11146645/2123721 中的一维矢量尽管该解决方案说适用于任意维数数组(这似乎意味着向量).有了这个,我可以做一个.prod(axis = 1),但这同样只对矢量有效.
I'm not sure if I need to use einsum, tensordot, meshgrid or some combination thereof to achieve this. I have a solution but only for single-dimension vectors from https://stackoverflow.com/a/11146645/2123721 even though that solution says to work for arbitrary dimensions array (which appears to mean vectors). With that one i can do a .prod(axis=1), but again this is only valid for vectors.
谢谢!
推荐答案
这是从broadcasting
以累积方式迭代地执行此操作的一种方法-
Here's one approach to do this iteratively in an accumulating manner making use of broadcasting
after extending dimensions for each pair from the list of arrays for elmentwise multiplications -
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)
这篇关于带有Numpy或TensorFlow的多个2D矩阵的高效轴向笛卡尔积的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!