0

Ceci est un peu liée à Numpy: cartesian product of x and y array points into single array of 2D pointsproduit cartésien de coordonnées arbitraires dimensions dans des tableaux arbitraires dimensions

Je suis à la recherche d'une manière concise pour créer un produit cartésien de deux tableaux avec dimensionnalité arbitraire.

Exemples:

similaires au fil lié, je veux

x = numpy.array([1,2,3]) #ndim 1 
y = numpy.array([4,5]) #ndim 1 
cartesian_product(x,y) == numpy.array([[[1, 4], 
             [2, 4], 
             [3, 4]], 
             [[1, 5], 
             [2, 5], 
             [3, 5]]]) #ndim "2" = ndim x + ndim y 

Le tableau résultant est 2 dimensions parce que [1, 4], [2, 4], etc. sont coordonnées et donc pas une vraie dimension. Pour généraliser, il pourrait être préférable d'écrire x/y comme [[1], [2], [3]].

Ce qui précède est égale à

numpy.dstack(numpy.meshgrid(x,y)) 

Mais je veux aussi

x2 = numpy.array([[1,1], [2,2], [3,3]]) #ndim "1", since [1, 1] is a coordinate 
cartesian_product(x2,y) == numpy.array([[[1, 1, 4], 
             [2, 2, 4], 
             [3, 3, 4]], 

             [[1, 1, 5], 
             [2, 2, 5], 
             [3, 3, 5]]]) #ndim 2 = ndim x2 + ndim y 


y2 = numpy.array([[10, 11], [20, 21]]) #ndim 1 
(cartesian_product(x2, y2) == 
numpy.array([[[1, 1, 10, 11], 
       [2, 2, 10, 11], 
       [3, 3, 10, 11]], 

      [[1, 1, 20, 21], 
       [2, 2, 20, 21], 
       [3, 3, 20, 21]]])) #ndim x2 + ndim y2 

x3 = numpy.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]]) #ndim 2 
(cartesian_product(x3, y) == 
numpy.array([[[[1, 2, 4], [3, 4, 4]], [[5, 6, 4], [7, 8, 4]]], 
      [[[1, 2, 5], [3, 4, 5]], [[5, 6, 5], [7, 8, 5]]]]) #ndim 3 

Pour visualiser ce que je suis en train de faire: Comme je l'ai dit, [[0, 0], [ 0, 1], [1, 1], [1, 0]] doit être interprété comme une liste de coordonnées à une dimension, ce qui correspond à une ligne. Si je fais ensuite un produit cartésien avec [1, 2, 3, 4], j'extrude cette ligne dans la direction z, en la transformant en surface (c'est-à-dire en 2 dimensions). Mais maintenant, le tableau sera bien sûr en 3 dimensions.

Je suppose que je peux trouver une solution pour résoudre cela avec des boucles, mais est-il possible d'y parvenir avec des outils numpy/scipy?

+0

Je ne comprends pas ce que vous entendez par "coordonnées". Le tableau de résultats dans votre premier exemple est en trois dimensions. Si vous l'entrez en numpy, il aura ndim 3. De même, tous vos exemples x2, y2, x3 ont plus de dimensions que vous ne le pensez. – BrenBarn

+0

Bien sûr [[1, 1], [2, 2]] est un tableau à deux dimensions. Mais dans la fonction de produit cartésien que je cherche, elle est essentiellement unidimensionnelle, puisque c'est juste une liste de coordonnées, [coord1, coord2]. [[coord11, coord12], [coord21, coord22]] serait "2" -dimensionnel, même si son tableau est 2 + 1-dimensionnel. C'est peut-être plus facile si j'essaie d'illustrer mon problème, disons que j'ai une courbe définie dans xy, ce sera une liste de coordonnées, mais une ligne est essentiellement unidimensionnelle. Ce que j'essaie de faire, c'est de l'extruder dans une autre dimension. – mueslo

Répondre

1

Une façon efficace de la mémoire est l'affectation broadcastés:

def cartesian_product(x, y): 
    if x.ndim < 2: 
     x = np.atleast_2d(x).T 
    if y.ndim < 2: 
     y = np.atleast_2d(y).T 

    sx, sy = x.shape, y.shape 
    sz = sy[:-1] + sx[:-1] + (sy[-1] + sx[-1],) 
    z = np.empty(sz, np.result_type(x, y)) 

    # Broadcasted assignment 
    z[...,:sx[-1]] = x 
    z[...,sx[-1]:] = y.reshape(sy[:-1] + (x.ndim-1)*(1,) + (sy[-1],)) 

    return z 

Si vous avez besoin des détails sur la radiodiffusion, this page vous a couvert.