Перемешать столбцы массива с помощью Numpy

Скажем, у меня есть массив r размерности (n, m). Я хотел бы перетасовать столбцы этого массива.

Если я использую numpy.random.shuffle(r), он перетасовывает строки. Как я могу только перетасовать столбцы? Чтобы первый столбец стал вторым, а третий - первым и т.д., Случайным образом.

Пример:

ввод:

array([[  1,  20, 100],
       [  2,  31, 401],
       [  8,  11, 108]])

выход:

array([[  20, 1, 100],
       [  31, 2, 401],
       [  11,  8, 108]])

Ответ 1

Пока я спрашивал, может быть, я мог бы перетасовать транспонированный массив:

 np.random.shuffle(np.transpose(r))

Похоже, что это делает работу. Я был бы признателен за комментарии, чтобы узнать, хороший ли это для этого.

Ответ 2

Для общей оси вы можете следовать шаблону:

>>> import numpy as np
>>> 
>>> a = np.array([[  1,  20, 100, 4],
...               [  2,  31, 401, 5],
...               [  8,  11, 108, 6]])
>>> 
>>> print a[:, np.random.permutation(a.shape[1])]
[[  4   1  20 100]
 [  5   2  31 401]
 [  6   8  11 108]]
>>> 
>>> print a[np.random.permutation(a.shape[0]), :]
[[  1  20 100   4]
 [  2  31 401   5]
 [  8  11 108   6]]
>>> 

Ответ 3

Итак, еще один шаг от вашего ответа:

Изменить: я очень легко ошибаюсь, как это работает, поэтому я вставляю свое понимание состояния матрицы на каждом шаге.

r == 1 2 3
     4 5 6
     6 7 8

r = np.transpose(r)  

r == 1 4 6
     2 5 7
     3 6 8           # Columns are now rows

np.random.shuffle(r)

r == 2 5 7
     3 6 8 
     1 4 6           # Columns-as-rows are shuffled

r = np.transpose(r)  

r == 2 3 1
     5 6 4
     7 8 6           # Columns are columns again, shuffled.

который затем вернется в правильную форму, с перегруппированными столбцами.

Транспортировка транспонированной матрицы == эта матрица или [A ^ T] ^ T == A. Итак, вам нужно сделать вторую транспозицию после тасования (поскольку транспонирование не является shuffle), чтобы он снова был в правильной форме.

Изменить: ответ OP пропускает сохранение транспозиций и вместо этого позволяет тасованию работать на r, как если бы оно было.

Ответ 4

В общем случае, если вы хотите перетасовать массив numpy вдоль оси i:

def shuffle(x, axis = 0):
    n_axis = len(x.shape)
    t = np.arange(n_axis)
    t[0] = axis
    t[axis] = 0
    xt = np.transpose(x.copy(), t)
    np.random.shuffle(xt)
    shuffled_x = np.transpose(xt, t)
    return shuffled_x

shuffle(array, axis=i)