Cartesian Product of arrays - PART 2

Viewed 87

My question posted recently, and capably answered, has a follow up that is a bit beyond my present capability. Consider two numpy 2d arrays, V1 and V2, that are identical.

V1 = np.array([[1, 2],
               [1, 3],
               [1, 4],
               [2, 3],
               [2, 4],
               [3, 4]])

V2 = np.array([[1, 2],
               [1, 3],
               [1, 4],
               [2, 3],
               [2, 4],
               [3, 4]])

Now, my goal is to construct a numpy array, V, having 4 columns. Think of this as a Cartesian product of numpy arrays V1 and V2. The entries in the first two columns of V are rows from V1, and the entries in the last two columns of V are rows taken from V2.

Here's the hard part - there is a tricky condition: In each row of V, at least one of the entries in the first two columns must have a match in the last two columns. For the simple example described here, V should look like:

V = np.array([[1,2,  1,2]
             [1,2,  1,3]
             [1,2,  1,4]
             [1,2,  2,3]
             [1,2,  2,4]

             [1,3,  1,2]
             [1,3,  1,3]
             [1,3,  1,4]
             [1,3,  2,3]
             [1,3,  3,4]

             [1,4,  1,2]
             [1,4,  1,3]
             [1,4,  1,4]
             [1,4,  2,4]
             [1,4,  3,4]

             [2,3,  1,2]
             [2,3,  1,3]
             [2,3,  2,3]
             [2,3,  2,4]
             [2,3,  3,4]

             [2,4,  1,2]
             [2,4,  1,4]
             [2,4,  2,3]
             [2,4,  2,4]
             [2,4,  3,4]

             [3,4,  1,3]
             [3,4,  1,4]
             [3,4,  2,3]
             [3,4,  2,4]
             [3,4,  3,4]])
1 Answers

Building on the answer of your previous question:

r,c = np.nonzero(np.equal.outer(V1,V2).any(axis=(1,3)))
np.c_[V1[r], V2[c]]

of course, you can apply similarly to other proposed answers in your previous question as well.

output:

np.array_equal(V,np.c_[V1[r], V2[c]])
#True


[[1 2 1 2]
 [1 2 1 3]
 [1 2 1 4]
 [1 2 2 3]
 [1 2 2 4]
 [1 3 1 2]
 [1 3 1 3]
 [1 3 1 4]
 [1 3 2 3]
 [1 3 3 4]
 [1 4 1 2]
 [1 4 1 3]
 [1 4 1 4]
 [1 4 2 4]
 [1 4 3 4]
 [2 3 1 2]
 [2 3 1 3]
 [2 3 2 3]
 [2 3 2 4]
 [2 3 3 4]
 [2 4 1 2]
 [2 4 1 4]
 [2 4 2 3]
 [2 4 2 4]
 [2 4 3 4]
 [3 4 1 3]
 [3 4 1 4]
 [3 4 2 3]
 [3 4 2 4]
 [3 4 3 4]]
Related