Перемешать массив с помощью python, рандомизировать порядок элементов массива с помощью python

Какой самый простой способ перетасовать массив с помощью Python?


person davethegr8    schedule 23.01.2009    source источник
comment
+1 за перенос наиболее полезных фрагментов документации python в всегда превосходный формат SO Q&A.   -  person charleslparker    schedule 26.04.2013
comment
есть ли вариант, который не изменяет исходный массив, но возвращает новый перетасованный массив?   -  person Charlie Parker    schedule 29.03.2017
comment
вы можете получить новый массив (немодифицированный) с помощью new_array = random.sample( array, len(array) ).   -  person Charlie Parker    schedule 29.03.2017


Ответы (10)


Альтернативный способ сделать это с помощью sklearn.

from sklearn.utils import shuffle
X=[1,2,3]
y = ['one', 'two', 'three']
X, y = shuffle(X, y, random_state=0)
print(X)
print(y)

Выход:

[2, 1, 3]
['two', 'one', 'three']

Преимущество: вы можете произвольно выбирать несколько массивов одновременно, не нарушая сопоставление. А 'random_state' может управлять перемешиванием для воспроизводимого поведения.

person Qy Zuo    schedule 24.07.2017
comment
Спасибо, очень полезно перетасовать сразу два массива. - person Dmitry; 15.12.2017
comment
Искал эту TNX! - person nOp; 13.03.2018
comment
это более полный (и часто более полезный), чем принятый ответ - person WestCoastProjects; 14.10.2018

Другие ответы самые простые, однако немного раздражает то, что метод random.shuffle на самом деле ничего не возвращает - он просто сортирует данный список. Если вы хотите объединить вызовы в цепочку или просто объявить перетасованный массив в одной строке, вы можете сделать:

    import random
    def my_shuffle(array):
        random.shuffle(array)
        return array

Затем вы можете сделать такие строки, как:

    for suit in my_shuffle(['hearts', 'spades', 'clubs', 'diamonds']):
person Mark Rhodes    schedule 20.12.2011
comment
Он ничего не возвращает специально, потому что пытается напомнить вам, что работает, изменяя ввод на месте. (Это может сэкономить память.) Ваша функция также изменяет свой ввод на месте. - person John Y; 21.12.2011
comment
Думаю, это стиль. Лично я предпочитаю, чтобы я мог написать одну строчку, чтобы добиться того, чего в противном случае потребовалась бы пара. Мне кажется странным, что язык, нацеленный на то, чтобы программы были как можно короче, в этих случаях не возвращает переданный объект. Поскольку он изменяет ввод на месте, вы можете без проблем заменить вызов random.shuffle на вызов этой версии. - person Mark Rhodes; 21.12.2011
comment
Python на самом деле не стремится быть максимально кратким. Python стремится сбалансировать удобочитаемость и выразительность. Так получилось, что это довольно кратко, в основном потому, что это язык очень высокого уровня. Собственные встроенные модули Python обычно (не всегда) стремятся либо быть функциональными (возвращать значение, но не иметь побочных эффектов) или быть процедурным (работать с побочными эффектами и ничего не возвращать). Это идет рука об руку с довольно строгим различием в Python между операторами и выражениями. - person John Y; 21.12.2011
comment
Отлично. Я предлагаю переименовать его в my_shuffle, чтобы сразу увидеть разницу в коде. - person Jabba; 23.02.2012
comment
Возможно, но это может быть преждевременная оптимизация (это может быть полезно, но необходимость перемешивания не требует явного возврата массива). Кроме того, shuffle (array), за которым следует некоторое использование shuffle, будет состоять только из 2 строк, в отличие от 3 + n (использование раз), хотя я думаю, это будет экономия, если вы будете использовать его много раз. Вот отличное видео, в котором обсуждаются такие вещи (например, фантомные требования и преждевременная оптимизация) - pyvideo.org/video/880/stop-writing-classes - person Aaron Newton; 21.04.2012

На всякий случай, если вам нужен новый массив, вы можете использовать sample:

import random
new_array = random.sample( array, len(array) )
person Charlie Parker    schedule 29.03.2017

При работе с обычными списками Python random.shuffle() выполнит работу, как показано в предыдущих ответах.

Но когда дело доходит до _2 _ (_ 3_), random.shuffle, похоже, ломает исходный ndarray. Вот пример:

import random
import numpy as np
import numpy.random

a = np.array([1,2,3,4,5,6])
a.shape = (3,2)
print a
random.shuffle(a) # a will definitely be destroyed
print a

Просто используйте: np.random.shuffle(a)

Как и random.shuffle, np.random.shuffle перемещает массив на место.

person Shuai Zhang    schedule 28.10.2013
comment
что именно означает уничтожено? (я имею в виду, в этом контексте - я не ELL.) - person dbliss; 15.07.2016
comment
Хорошо, если я попробую A = np.array (range (9)). Reshape ([3,3]) - person Nicholas McCarthy; 10.08.2017

Вы можете отсортировать свой массив со случайным ключом

sorted(array, key = lambda x: random.random())

ключ можно прочитать только один раз, поэтому сравнение элементов во время сортировки по-прежнему эффективно.

но похоже, что random.shuffle(array) будет быстрее, так как он написан на C

это O (log (N)) кстати

person Trinh Hoang Nhu    schedule 21.09.2018
comment
создает ли это новый случайный элемент для каждого элемента массива? - person WestCoastProjects; 14.10.2018
comment
@javadba Нет, это просто отсортирует массив по случайному индексу, что приведет к перемешиванию массива - person Trinh Hoang Nhu; 17.10.2018
comment
Извините, я, возможно, не понял, я не имел в виду array. Я имел в виду элемент Random: т.е. в lambda random.random() мог каждый раз генерировать новый экземпляр класса Random. Я не совсем уверен: в java это было бы неправильным способом: вы должны создать Random rng = Random(), а затем вызвать rng.nextGaussian(). Но не знаю, как работает python random.random() - person WestCoastProjects; 17.10.2018
comment
Хотя ваш код может быть исправлен в качестве ответа, но уточняя, что делает ваш код, он может улучшить качество вашего ответа. Ознакомьтесь со статьей: Как мне написать хороший ответ? - person LuFFy; 17.10.2018

В дополнение к предыдущим ответам я хотел бы представить еще одну функцию.

numpy.random.shuffle, а также random.shuffle выполняют перемешивание на месте. Однако, если вы хотите вернуть перемешанный массив, numpy.random.permutation - это функция, которую следует использовать.

person Saber    schedule 18.11.2016

Я не знаю, что использовал random.shuffle(), но он вернул мне "None", поэтому я написал это, может быть полезно для кого-то

def shuffle(arr):
    for n in range(len(arr) - 1):
        rnd = random.randint(0, (len(arr) - 1))
        val1 = arr[rnd]
        val2 = arr[rnd - 1]

        arr[rnd - 1] = val1
        arr[rnd] = val2

    return arr
person Jeeva    schedule 17.01.2017
comment
да, он возвращает None, но массив изменен, если вы действительно хотите что-то вернуть, сделайте это import random def shuffle (arr): random.shuffle (arr) return arr - person user781903; 08.02.2017

Имейте в виду, что random.shuffle() не следует использовать в многомерных массивах, поскольку это вызывает повторения.

Представьте, что вы хотите перетасовать массив по его первому измерению, мы можем создать следующий тестовый пример,

import numpy as np
x = np.zeros((10, 2, 3))

for i in range(10):
   x[i, ...] = i*np.ones((2,3))

так что вдоль первой оси i-й элемент соответствует матрице 2x3, где все элементы равны i.

Если мы используем правильную функцию перемешивания для многомерных массивов, то есть np.random.shuffle(x), массив будет перемещаться по первой оси по желанию. Однако использование random.shuffle(x) вызовет повторы. Вы можете проверить это, запустив len(np.unique(x)) после перемешивания, что даст вам 10 (как и ожидалось) с np.random.shuffle(), но только около 5 при использовании random.shuffle().

person Wise Cloud    schedule 21.02.2020

person    schedule
comment
есть ли вариант, который не изменяет исходный массив, но возвращает новый перетасованный массив? - person Charlie Parker; 29.03.2017
comment
@Charlie Это было бы хорошо задать отдельный вопрос. (Может, кто-то уже об этом спрашивал.) - person David Z; 29.03.2017
comment
По иронии судьбы, эта страница стала самой популярной в Google, когда я просто искал массив перетасовки python. - person Joshua Huber; 10.05.2018
comment
@Charlie люди Google эти вопросы, чтобы они могли найти ответы на них в таких местах, как переполнение стека. Пока это не дубликат, нет ничего плохого в том, чтобы сделать переполнение стека опцией в качестве ресурса. - person Matt; 08.07.2018
comment
@ {Чарли Паркер} Просто сделайте копию исходного массива перед использованием random.shuffle: `copy_of array = array.copy () random.shuffle (copy_of_array)` - person Bobby Zandavi; 02.06.2020
comment
@CharlieParker Из документов python shuffled = sample(array, k=len(array)) - person allenh; 10.06.2021

person    schedule
comment
есть ли вариант, который не изменяет исходный массив, но возвращает новый перетасованный массив? - person Charlie Parker; 29.03.2017
comment
@CharlieParker new_array = list(array); random.shuffle(new_array) - person James Parker; 21.08.2020
comment
для тех, кто концептуально не понимает, что делает new_array = list(array); random.shuffle(new_array), поскольку они не являются командами в отдельных строках. Джеймс сначала создает копию, а затем перетасовывает массив. - person Charlie Parker; 23.08.2020