在numpy矩阵中一次随机排列一列的有效方法

Don*_*beo 2 python performance numpy matrix

我需要一个numpy矩阵的所有列一个一个地洗牌。这是我当前的代码

n, p = X.shape
val = []
for i in range(p):
    Xt = X.copy()
    np.random.shuffle(Xt[:, i])
    print(Xt)
Run Code Online (Sandbox Code Playgroud)

我每次都复制X到变量Xt。这似乎效率很低。

如何加快此代码的速度?

编辑:给出的例子

`X= [[0 3 6]
    [1 4 7]
    [2 5 8]]`
Run Code Online (Sandbox Code Playgroud)

for循环的预期输出为:

>>> [[2 3 6]
 [1 4 7]
 [0 5 8]] 

[[0 5 6]
 [1 4 7]
 [2 3 8]] 

[[0 3 7]
 [1 4 8]
 [2 5 6]] 

>>> 
Run Code Online (Sandbox Code Playgroud)

每次仅应改组一列。所有其他列应具有与原始矩阵相同的值

tom*_*m10 5

可以将numpy中的列改组到位,并且完全不需要复制:

import numpy as np
X = np.arange(25).reshape(5,5).transpose()
print X
np.random.shuffle(X[:,2])  # here, X[:,2] is a just a view onto this column of X
print X
Run Code Online (Sandbox Code Playgroud)

输出为:

[[ 0  1  2  3  4]  # the original
 [ 5  6  7  8  9]
 [10 11 12 13 14]
 [15 16 17 18 19]
 [20 21 22 23 24]]

[[ 0  1  2  3  4]  # note that the middle column is shuffled here
 [ 5  6 12  8  9]
 [10 11 22 13 14]
 [15 16 17 18 19]
 [20 21  7 23 24]]
Run Code Online (Sandbox Code Playgroud)

您正在进行大量复制,很难确定是否有任何复制满足您的整体需求,但不需要洗牌。

编辑:
尽管此问题是按照改组的方式编写的,但由于改组可以在适当的地方进行,因此实际的效率低下是由于复制所致。因此,问题就变成了OP在拷贝方面需要什么?由于需要还原原始数组,因此需要某些其他索引或数组值的某些副本或副本。在这种情况下,唯一的效率是希望不必在每个循环中都复制整个数组,而只需复制列(或者基本上等效,一次复制整个矩阵),而不是复制矩阵p -times,如问题示例中所述,@ ajcr)。以下生成器仅逐行执行此操作:

def sc(x):
    p = X.shape[1]
    for i in range(p):
        hold = np.array(x[:,i])
        np.random.shuffle(x[:,i])
        yield x
        x[:,i] = hold

for i in sc(X):
    print i
Run Code Online (Sandbox Code Playgroud)

这使:

[[ 2  5 11 15 20]    # #0 column shuffled
 [ 3  6 10 16 21]
 [ 0  7 14 17 22]
 [ 4  8 13 18 23]
 [ 1  9 12 19 24]]

[[ 0  5 11 15 20]    # #1 column shuffled
 [ 1  8 10 16 21]
 [ 2  9 14 17 22]
 [ 3  7 13 18 23]
 [ 4  6 12 19 24]]

#  etc
Run Code Online (Sandbox Code Playgroud)

另一方面,如果整个数组每个列的移位都需要一个新的副本,那是时间的流逝,并且列是一个接一个还是全部都被混洗等等都没关系。