matriz numpy a matriz de permutación

np.array([1,2,3]) 

Tengo una matriz de números. Me gustaría convertirlo en una matriz numpy con tuplas de cada permutación 1: 1. Me gusta esto:

 np.array([ [(1,1),(1,2),(1,3)], [(2,1),(2,2),(2,3)], [(3,1),(3,2),(3,3)], ]) 

¿Alguna idea sobre cómo hacer esto de manera eficiente? Necesito hacer esta operación unos cuantos millones de veces.

Si está trabajando con numpy, no trabaje con tuplas. Usa su poder y agrega otra dimensión de tamaño dos. Mi recomendación es:

 x = np.array([1,2,3]) np.vstack(([np.vstack((x, x, x))], [np.vstack((x, x, x)).T])).T 

o:

 im = np.vstack((x, x, x)) np.vstack(([im], [im.T])).T 

Y para un conjunto general:

 ix = np.vstack([x for _ in range(x.shape[0])]) return np.vstack(([ix], [ix.T])).T 

Esto producirá lo que quieres:

 array([[[1, 1], [1, 2], [1, 3]], [[2, 1], [2, 2], [2, 3]], [[3, 1], [3, 2], [3, 3]]]) 

Pero como una matriz 3D, como puedes ver cuando miras su forma:

 Out[25]: (3L, 3L, 2L) 

Esto es más eficiente que la solución con permutaciones a medida que aumenta el tamaño de la matriz. Sincronizar mi solución contra @ Kasra produce 1 ms para la mía frente a 46 ms para la que tiene permutaciones para un conjunto de tamaño 100. Sin embargo, la solución de @ AshwiniChaudhary es más eficiente.

Puedes hacer algo como esto:

 >>> a = np.array([1, 2, 3]) >>> n = a.size >>> np.vstack((np.repeat(a, n), np.tile(a, n))).T.reshape(n, n, 2) array([[[1, 1], [1, 2], [1, 3]], [[2, 1], [2, 2], [2, 3]], [[3, 1], [3, 2], [3, 3]]]) 

O según lo sugerido por @Jaime , puede obtener una aceleración de aproximadamente 10x si aprovechamos la transmisión aquí:

 >>> a = np.array([1, 2, 3]) >>> n = a.size >>> perm = np.empty((n, n, 2), dtype=a.dtype) perm[..., 0] = a[:, None] perm[..., 1] = a ... >>> perm array([[[1, 1], [1, 2], [1, 3]], [[2, 1], [2, 2], [2, 3]], [[3, 1], [3, 2], [3, 3]]]) 

Comparaciones de tiempo:

 >>> a = np.array([1, 2, 3]*100) >>> %%timeit np.vstack((np.repeat(a, n), np.tile(a, n))).T.reshape(n, n, 2) ... 1000 loops, best of 3: 934 µs per loop >>> %%timeit perm = np.empty((n, n, 2), dtype=a.dtype) perm[..., 0] = a[:, None] perm[..., 1] = a ... 10000 loops, best of 3: 111 µs per loop 

Puede usar itertools.product para obtener las permutaciones y luego convertir el resultado en numpy matriz numpy .

 >>> from itertools import product >>> p=list(product(a,repeat=2)) >>> np.array([p[i:i+3] for i in range(0,len(p),3)]) array([[[1, 1], [1, 2], [1, 3]], [[2, 1], [2, 2], [2, 3]], [[3, 1], [3, 2], [3, 3]]]) 

Otra forma más usando numpy.meshgrid .

 >>> x = np.array([1, 2, 3]) >>> perms = np.stack(np.meshgrid(x, x)) >>> perms array([[[1, 2, 3], [1, 2, 3], [1, 2, 3]], [[1, 1, 1], [2, 2, 2], [3, 3, 3]]]) >>> perms.transpose().reshape(9, 2) array([[1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3], [3, 1], [3, 2], [3, 3]])