Prodotto cartesiano per riga tra un array 1d e un array 2d
Penso che mi manchi qualcosa di ovvio. Voglio trovare un prodotto cartesiano di arr1 (una matrice NumPy 1D), e le RIGHE di arr2 (una matrice NumPy 2d). Quindi, se arr1 ha 4 elementi e arr2 ha forma (5,2), l'output dovrebbe avere forma (20,3). (vedi sotto)
import numpy as np
arr1 = np.array([1, 4, 7, 3])
arr2 = np.array([[0, 1],
[2, 3],
[4, 5],
[4, 0],
[9, 9]])
L'output desiderato è:
arr3 = np.array([[1, 0, 1],
[1, 2, 3],
[1, 4, 5],
[1, 4, 0],
[1, 9, 9],
[4, 0, 1],
[4, 2, 3],
[4, 4, 5],
[4, 4, 0],
[4, 9, 9],
[7, 0, 1],
[7, 2, 3],
[7, 4, 5],
[7, 4, 0],
[7, 9, 9],
[3, 0, 1],
[3, 2, 3],
[3, 4, 5],
[3, 4, 0],
[3, 9, 9]])
Ho provato a usare Transpose e Reshape con codice come np.array (np.meshgrid (arr1, arr2)), ma ancora senza successo.
Spero che la soluzione possa essere generalizzata perché devo anche affrontare situazioni come questa: Ottieni tutte le combinazioni delle RIGHE di un array 2d (10,2) e delle RIGHE di un array 2d (20, 5) per ottenere un matrice di output (200,7).
Risposte
Ecco una soluzione vettorializzata che funziona anche per il tuo caso generale:
arr1 = np.array([[1, 4],
[7, 3]])
arr2 = np.array([[0, 1],
[2, 3],
[4, 5],
[4, 0],
[9, 9]])
np.hstack((np.repeat(arr1,len(arr2),0),np.stack((arr2,)*len(arr1)).reshape(-1,arr2.shape[1])))
output di forma (2,2)* (5,2)-> (10,4):
[[1 4 0 1]
[1 4 2 3]
[1 4 4 5]
[1 4 4 0]
[1 4 9 9]
[7 3 0 1]
[7 3 2 3]
[7 3 4 5]
[7 3 4 0]
[7 3 9 9]]
Puoi usare hstack per aggiungere colonne ad arr2 e vstack per ottenere l'array finale.
np.vstack(np.apply_along_axis(lambda x: np.hstack([np.repeat(x[0], arr2.shape[0]).reshape(-1, 1),
arr2]),
1,
arr1[:, None]))
Penso che questo dovrebbe farlo:
import numpy as np
arr0 = np.array([1, 4, 7, 3])
arr1 = np.reshape(arr0, (len(arr0),1))
arr2 = np.array([[0, 1],
[2, 3],
[4, 5],
[4, 0],
[9, 9]])
r1,c1 = arr1.shape
r2,c2 = arr2.shape
arrOut = np.zeros((r1,r2,c1+c2), dtype=arr1.dtype)
arrOut[:,:,:c1] = arr1[:,None,:]
arrOut[:,:,c1:] = arr2
arrOut.reshape(-1,c1+c2)
L'output è:
array([[1, 0, 1],
[1, 2, 3],
[1, 4, 5],
[1, 4, 0],
[1, 9, 9],
[4, 0, 1],
[4, 2, 3],
[4, 4, 5],
[4, 4, 0],
[4, 9, 9],
[7, 0, 1],
[7, 2, 3],
[7, 4, 5],
[7, 4, 0],
[7, 9, 9],
[3, 0, 1],
[3, 2, 3],
[3, 4, 5],
[3, 4, 0],
[3, 9, 9]])
Pulito e facile
In base a come hai visualizzato l'output desiderato in questione. Ha forma di (4,5,3). se è il caso, la soluzione è sotto e, in caso contrario, modifica l'array di output nella tua domanda.
import numpy as np
arr1 = np.array([1, 4, 7, 3])
arr2 = np.array([[0, 1],
[2, 3],
[4, 5],
[4, 0],
[9, 9]])
arr3 = np.broadcast_to(arr1[:, np.newaxis, np.newaxis], (4,5,1))
print(arr3.shape)
(4, 5, 1)
print(arr3)
[[[1]
[1]
[1]
[1]
[1]]
[[4]
[4]
[4]
[4]
[4]]
[[7]
[7]
[7]
[7]
[7]]
[[3]
[3]
[3]
[3]
[3]]]
arr4 = np.broadcast_to(arr2[np.newaxis, :, :], (4,5,2))
print(arr4.shape)
(4, 5, 2)
print(arr4)
[[[0 1]
[2 3]
[4 5]
[4 0]
[9 9]]
[[0 1]
[2 3]
[4 5]
[4 0]
[9 9]]
[[0 1]
[2 3]
[4 5]
[4 0]
[9 9]]
[[0 1]
[2 3]
[4 5]
[4 0]
[9 9]]]
arr5 = np.concatenate([arr3, arr4], axis=-1)
print(arr5.shape)
(4, 5, 3)
print(arr5)
[[[1 0 1]
[1 2 3]
[1 4 5]
[1 4 0]
[1 9 9]]
[[4 0 1]
[4 2 3]
[4 4 5]
[4 4 0]
[4 9 9]]
[[7 0 1]
[7 2 3]
[7 4 5]
[7 4 0]
[7 9 9]]
[[3 0 1]
[3 2 3]
[3 4 5]
[3 4 0]
[3 9 9]]]