numpy数组到置换矩阵

use*_*329 3 python arrays performance numpy permutation

np.array([1,2,3])
Run Code Online (Sandbox Code Playgroud)

我有阵容.我想把它变成一个numpy数组,每个1:1排列的元组.像这样:

np.array([
    [(1,1),(1,2),(1,3)],
    [(2,1),(2,2),(2,3)],
    [(3,1),(3,2),(3,3)],
])
Run Code Online (Sandbox Code Playgroud)

有关如何有效地做到这一点的任何想法?我需要做几百万次这个操作.

Ash*_*ary 6

你可以这样做:

>>> 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]]])
Run Code Online (Sandbox Code Playgroud)

或者按照@Jaime的建议,如果我们利用这里的广播,你可以获得大约10倍的加速:

>>> 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]]])
Run Code Online (Sandbox Code Playgroud)

时间比较:

>>> 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
Run Code Online (Sandbox Code Playgroud)

  • 如果你远离平铺并重复使用广播,你可以得到一个大的加速(100项数组的10倍):`perm = np.empty((n,n,2),dtype = a.dtype) ; 烫发[...,0] = a; 烫发[...,1] = a [:无]` (2认同)

Kor*_*rem 5

如果您正在使用 numpy,请不要使用元组。使用它的力量并添加另一个大小为 2 的维度。我的建议是:

x = np.array([1,2,3])
np.vstack(([np.vstack((x, x, x))], [np.vstack((x, x, x)).T])).T
Run Code Online (Sandbox Code Playgroud)

或者:

im = np.vstack((x, x, x))
np.vstack(([im], [im.T])).T
Run Code Online (Sandbox Code Playgroud)

对于一般数组:

ix = np.vstack([x for _ in range(x.shape[0])])
return np.vstack(([ix], [ix.T])).T
Run Code Online (Sandbox Code Playgroud)

这将产生你想要的:

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

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

       [[3, 1],
        [3, 2],
        [3, 3]]])
Run Code Online (Sandbox Code Playgroud)

但是作为一个 3D 矩阵,正如您在查看其形状时所看到的:

Out[25]: (3L, 3L, 2L)
Run Code Online (Sandbox Code Playgroud)

随着数组大小变大,这比具有排列的解决方案更有效。针对@Kasra 的解决方案计时,我的解决方案为 1 毫秒,而对大小为 100 的数组进行排列的解决方案为 46 毫秒。不过,@AshwiniChaudhary 的解决方案效率更高。