Approach #1
Use np.meshgrid
and then np.array
and a final transpose -
np.array(np.meshgrid(A,B)).T.reshape(-1,2)
Sample run -
In [3]: A
Out[3]: array([1, 2, 3, 4])
In [4]: B
Out[4]: array([5, 6, 7, 8, 9])
In [5]: np.array(np.meshgrid(A,B)).T.reshape(-1,2)
Out[5]:
array([[1, 5],
[1, 6],
[1, 7],
[1, 8],
[1, 9],
[2, 5],
[2, 6],
[2, 7],
[2, 8],
[2, 9],
[3, 5],
[3, 6],
[3, 7],
[3, 8],
[3, 9],
[4, 5],
[4, 6],
[4, 7],
[4, 8],
[4, 9]])
Approach #2
Initialization based approach with focus on performance, especially for large arrays -
def initialization_based(A,B):
N = A.size
M = B.size
out = np.empty((N,M,2),dtype=A.dtype)
out[...,0] = A[:,None]
out[...,1] = B
out.shape = (-1,2)
return out
Runtime test
In [7]: A = np.random.randint(0,9,(100))
In [8]: B = np.random.randint(0,9,(100))
In [9]: %timeit np.array(np.meshgrid(A,B)).T.reshape(-1,2)
10000 loops, best of 3: 69.1 µs per loop
In [10]: %timeit initialization_based(A,B)
100000 loops, best of 3: 11.1 µs per loop
Including approaches from other posts with the same setup -
In [183]: from itertools import product
# @Chris Mueller's soln
In [184]: %timeit [x for x in product(A,B)]
1000 loops, best of 3: 503 µs per loop
# @jyotish's soln
In [185]: %timeit [[i, j] for i in A for j in B]
1000 loops, best of 3: 1.34 ms per loop