2017-06-02 4 views
1

Donc d'abord, je pense que ce que j'essaie de réaliser est une sorte de produit cartésien mais élémentaire, à travers les colonnes seulement.Produit cartésien efficace de plusieurs matrices 2D avec Numpy ou TensorFlow

Ce que je suis en train de faire est, si vous avez plusieurs tableaux 2D de taille [(N, D1), (N, D2), (N, D3) ... (N, Dn)]

Le résultat est donc d'être un produit combinatoire sur l'axe = 1 tel que le résultat final sera alors de forme (N, D) où 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 ]]) 

et extensible à cartesian_product ([A, B, C, D ...], axe = 1)

par exemple

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

I présentent une solution de travail qui crée essentiellement une matrice vide (N, D) et la diffusion d'un produit de vecteur en colonne pour chaque colonne à l'intérieur des boucles imbriquées pour pour chaque matrice dans la liste fournie. Clairement, c'est horrible une fois que les tableaux deviennent plus grands!

Existe-t-il une solution existante dans numpy ou tensorflow pour cela? Potentiellement un qui est efficacement paralleizable (Une solution de tensorflow serait merveilleuse mais un chiffre est correct et tant que la logique de vecteur est claire alors il ne devrait pas être difficile de faire un équivalent tf)

Je ne sais pas si J'ai besoin d'utiliser einsum, tensordot, meshgrid ou une combinaison de ceux-ci pour y parvenir. J'ai une solution, mais seulement pour les vecteurs à dimension unique de https://stackoverflow.com/a/11146645/2123721 même si cette solution dit de travailler pour un tableau de dimensions arbitraires (ce qui semble signifier des vecteurs). Avec celui-là, je peux faire un .prod (axis = 1), mais encore une fois cela n'est valable que pour les vecteurs.

merci!

+0

Comment avez-vous ces multiples tableaux 2D stockés? Comme une liste de tableaux? Ou peut-être comme un tableau 3D? – Divakar

+0

@Divakar Pour l'instant, les multiples tableaux 2D sont stockés en mémoire, dans une liste selon l'exemple [A, B ...]. Ceux-ci sont le résultat d'une étape précédente de produit scalaire diffusé. Pour l'instant, c'est ok et ce n'est pas un goulot d'étranglement pour les stocker individuellement. S'il y a des suggestions pour optimiser cette étape aussi, je suis tout ouïe! – undercurrent

Répondre

1

Voici une approche pour faire itérativement de manière à accumuler en utilisant des broadcasting après l'extension des dimensions pour chaque paire de la liste des tableaux pour 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) 
+0

brillant! cela fonctionne parfaitement (Environ x10 plus rapide que ma méthode actuelle comme détaillé dans le PO) – undercurrent