Approach #1 : One approach would be -
x[np.argwhere(~np.eye(len(x),dtype=bool))]
Approach #2 : In two steps -
r = np.arange(len(x))
out = x[np.argwhere(r[:,None]!=r)]
Approach #3 : For performance, it might be better to create those pairwise coordinates and then mask. To get the paiwise coordinates, let's use cartesian_product_transpose
, like so -
r = np.arange(len(x))
mask = r[:,None]!=r
out = cartesian_product_transpose(x,x)[mask.ravel()]
Approach #4 : Another with np.broadcast_to
that avoids making copies until masking, again meant as a performance measure -
n = len(x)
r = np.arange(n)
mask = r[:,None]!=r
c0 = np.broadcast_to(x[:,None], (n, n))[mask]
c1 = np.broadcast_to(x, (n,n))[mask]
out = np.column_stack((c0,c1))
Runtime test -
In [382]: x = np.random.randint(0,9,(1000))
# @tom10's soln
In [392]: %timeit list(itertools.permutations(x, 2))
10 loops, best of 3: 62 ms per loop
In [383]: %%timeit
...: x[np.argwhere(~np.eye(len(x),dtype=bool))]
100 loops, best of 3: 11.4 ms per loop
In [384]: %%timeit
...: r = np.arange(len(x))
...: out = x[np.argwhere(r[:,None]!=r)]
100 loops, best of 3: 12.9 ms per loop
In [388]: %%timeit
...: r = np.arange(len(x))
...: mask = r[:,None]!=r
...: out = cartesian_product_transpose(x,x)[mask.ravel()]
100 loops, best of 3: 16.5 ms per loop
In [389]: %%timeit
...: n = len(x)
...: r = np.arange(n)
...: mask = r[:,None]!=r
...: c0 = np.broadcast_to(x[:,None], (n, n))[mask]
...: c1 = np.broadcast_to(x, (n,n))[mask]
...: out = np.column_stack((c0,c1))
100 loops, best of 3: 6.72 ms per loop