为 2D NumPy 数组的每一行高效应用不同的排列

Ton*_*ony 3 python arrays random numpy

给定一个矩阵 A,我想对 A 的不同行应用不同的随机洗牌;例如,

array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])
Run Code Online (Sandbox Code Playgroud)

变成

array([[1, 3, 2],
       [6, 5, 4],
       [7, 9, 8]])
Run Code Online (Sandbox Code Playgroud)

当然我们可以循环矩阵,让每一行随机打乱;然而迭代很慢,我问是否有更有效的方法来做到这一点。

cs9*_*s95 5

从 Divakar 那里学到了这个巧妙的技巧,其中涉及randnargsort

\n\n
np.random.seed(0)\n\ns = np.arange(16).reshape(4, 4)\nnp.take_along_axis(s, np.random.randn(*s.shape).argsort(axis=1), axis=1)\n\narray([[ 1,  0,  3,  2],\n       [ 4,  6,  5,  7],\n       [11, 10,  8,  9],\n       [14, 12, 13, 15]])\n
Run Code Online (Sandbox Code Playgroud)\n\n

对于二维数组,可以简化为

\n\n
s[np.arange(len(s))[:,None], np.random.randn(*s.shape).argsort(axis=1)]\n\narray([[ 1,  0,  3,  2],\n       [ 4,  6,  5,  7],\n       [11, 10,  8,  9],\n       [14, 12, 13, 15]])\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n\n

您还可以np.random.permutation独立地应用于每一行以返回一个新数组。

\n\n
np.apply_along_axis(np.random.permutation, axis=1, arr=s)\n\narray([[ 3,  1,  0,  2],\n       [ 4,  6,  5,  7],\n       [ 8,  9, 10, 11],\n       [15, 14, 13, 12]])\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n\n

表现 -

\n\n
s = np.arange(10000 * 100).reshape(10000, 100) \n\n%timeit s[np.arange(len(s))[:,None], np.random.randn(*s.shape).argsort(axis=1)] \n%timeit np.apply_along_axis(np.random.permutation, 1, s)   \n\n84.6 ms \xc2\xb1 857 \xc2\xb5s per loop (mean \xc2\xb1 std. dev. of 7 runs, 10 loops each)\n842 ms \xc2\xb1 8.06 ms per loop (mean \xc2\xb1 std. dev. of 7 runs, 1 loop each)\n
Run Code Online (Sandbox Code Playgroud)\n\n

我注意到这取决于数据的维度,请务必先对其进行测试。

\n