есть ли опция, которая не изменяет исходный массив, но возвращает новый перемешанный массив?
Чарли Паркер
@Charlie Это было бы неплохо задать в отдельном вопросе. (Может быть, кто-то еще уже спросил об этом.)
David Z
13
По иронии судьбы, эта страница стала хитом в Google, когда я только что искал «массив питонов shuffle»
Джошуа Хубер
2
@ Чарли люди Google эти вопросы, чтобы они могли найти ответы на них в таких местах, как переполнение стека. Пока это не дубликат, нет ничего плохого в том, чтобы сделать переполнение стека опцией в качестве ресурса
Мэтт
@javadba На самом деле это был ответ на первый вопрос. Нет ничего плохого в том, чтобы задавать вопросы о переполнении стека, даже если это можно было найти, покопавшись в Google. Это позволяет будущим людям найти ответ на стеке потока, когда они сами копают.
есть ли опция, которая не изменяет исходный массив, но возвращает новый перемешанный массив?
Чарли Паркер
36
Альтернативный способ сделать это с помощью 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» может контролировать перетасовку для воспроизводимого поведения.
Спасибо, очень полезно перетасовать два массива одновременно.
Дмитрий
1
Искал это, TNX!
Ноябрь
2
это более полный (и часто более полезный), чем принятый ответ
Джавадба
21
Остальные ответы самые простые, однако немного раздражает, что random.shuffleметод на самом деле ничего не возвращает - он просто сортирует заданный список. Если вы хотите объединить вызовы или просто иметь возможность объявлять перемешанный массив в одну строку, вы можете сделать следующее:
import random
def my_shuffle(array):
random.shuffle(array)return array
Тогда вы можете сделать такие строки:
for suit in my_shuffle(['hearts','spades','clubs','diamonds']):
Он ничего не возвращает конкретно, потому что пытается напомнить вам, что работает, изменяя ввод на месте. (Это может сэкономить память.) Ваша функция также меняет свой ввод.
Джон Y
2
Я думаю, это стиль. Лично я предпочитаю тот факт, что я могу написать одну строку, чтобы добиться того, что в противном случае было бы парой. Мне кажется странным, что язык, который нацелен на то, чтобы программы были как можно более короткими, не склонен возвращать переданный объект в этих случаях. Поскольку он изменяет ввод на месте, вы можете заменить вызов random.shuffle на вызов этой версии без проблем.
Марк Родс
12
Python на самом деле не стремится быть максимально кратким. Python стремится сбалансировать читабельность с выразительностью. Так получилось довольно кратко, главным образом потому, что это язык очень высокого уровня. Собственные встроенные функции Python обычно (не всегда) стремятся либо быть «подобными функции» (возвращать значение, но не иметь побочных эффектов), либо быть «подобными процедуре» (работать через побочные эффекты и ничего не возвращать). Это идет рука об руку с довольно строгим различием Python между утверждениями и выражениями.
Джон Y
Ницца. Я предлагаю переименовать его в my_shuffle, чтобы сразу увидеть разницу в коде.
Джабба
Возможно, но это может быть преждевременной оптимизацией (это может быть полезно, но необходимость перестановки не требует явного возврата массива). Кроме того, shuffle (массив), за которым следует некоторое использование shuffle, будет состоять всего из 2 строк, а не 3 + n (использование раз), хотя я полагаю, что это будет экономия, если вы будете использовать его много раз. Вот отличное видео, в котором обсуждаются подобные
Аарон Ньютон,
12
При работе с обычными списками Python, random.shuffle()сделайте работу так же, как показывают предыдущие ответы.
Но когда дело доходит до ndarray( numpy.array), 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 destroyedprint a
Просто используйте: np.random.shuffle(a)
Мол random.shuffle, np.random.shuffleтасует массив на месте.
это создает новый случайный элемент для каждого элемента массива?
Джавадба
@javadba Нет, это просто сортировка массива по случайному индексу, который в конечном итоге перетасует массив
Trinh Hoang Nhu
1
К сожалению я был , возможно , не ясно , что я не имею в виду , arrayя имел в виду Randomэлемент: то есть в может быть генерирующим новым экземпляр класса каждый раз. На самом деле я не уверен: это был бы неправильный способ сделать это: вы должны создать и затем вызвать . Но не уверен, как работает Pythonlambdarandom.random()RandomjavaRandom rng = Random()rng.nextGaussian()random.random()
Javadba
1
Хотя ваш код может корректироваться как ответ, но если вы уточните, что делает ваш код, это может улучшить качество вашего ответа. Оформить заказ статьи: Как мне написать хороший ответ?
LuFFy
1
В дополнение к предыдущим ответам я хотел бы представить еще одну функцию.
numpy.random.shuffleа также random.shuffleвыполнять перетасовку на месте. Однако, если вы хотите вернуть перетасованный массив, numpy.random.permutationэто функция для использования.
да, он возвращает None, но массив модифицируется, если вы действительно хотите что-то вернуть, тогда выполните этот импорт random def shuffle (arr): random.shuffle (arr) return arr
user781903
0
# arr = numpy array to shuffledef shuffle(arr):
a = numpy.arange(len(arr))
b = numpy.empty(1)for i in range(len(arr)):
sel = numpy.random.random_integers(0, high=len(a)-1, size=1)
b = numpy.append(b, a[sel])
a = numpy.delete(a, sel)
b = b[1:].astype(int)return arr[b]
Помните, что 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().
new_array = random.sample( array, len(array) )
.Ответы:
источник
источник
Альтернативный способ сделать это с помощью sklearn
Вывод:
Преимущество: вы можете рандомизировать несколько массивов одновременно, не нарушая отображение. И «random_state» может контролировать перетасовку для воспроизводимого поведения.
источник
Остальные ответы самые простые, однако немного раздражает, что
random.shuffle
метод на самом деле ничего не возвращает - он просто сортирует заданный список. Если вы хотите объединить вызовы или просто иметь возможность объявлять перемешанный массив в одну строку, вы можете сделать следующее:Тогда вы можете сделать такие строки:
источник
При работе с обычными списками Python,
random.shuffle()
сделайте работу так же, как показывают предыдущие ответы.Но когда дело доходит до
ndarray
(numpy.array
),random.shuffle
кажется, сломать оригиналndarray
. Вот пример:Просто используйте:
np.random.shuffle(a)
Мол
random.shuffle
,np.random.shuffle
тасует массив на месте.источник
На всякий случай, если вы хотите новый массив, вы можете использовать
sample
:источник
Вы можете отсортировать ваш массив со случайным ключом
ключ читается только один раз, поэтому сравнение элементов во время сортировки остается эффективным.
но похоже
random.shuffle(array)
будет быстрее так как написано на Систочник
array
я имел в видуRandom
элемент: то есть в может быть генерирующим новым экземпляр класса каждый раз. На самом деле я не уверен: это был бы неправильный способ сделать это: вы должны создать и затем вызвать . Но не уверен, как работает Pythonlambda
random.random()
Random
java
Random rng = Random()
rng.nextGaussian()
random.random()
В дополнение к предыдущим ответам я хотел бы представить еще одну функцию.
numpy.random.shuffle
а такжеrandom.shuffle
выполнять перетасовку на месте. Однако, если вы хотите вернуть перетасованный массив,numpy.random.permutation
это функция для использования.источник
Я не знаю, использовал ли
random.shuffle()
он, но он возвращает «None» мне, поэтому я написал это, может быть полезным для кого-тоисточник
источник
Помните, что
random.shuffle()
не следует использовать многомерные массивы, поскольку это вызывает повторения.Представьте, что вы хотите перетащить массив вдоль его первого измерения, мы можем создать следующий тестовый пример:
так что вдоль первой оси i-й элемент соответствует матрице 2x3, где все элементы равны i.
Если мы используем правильную функцию тасования для многомерных массивов, т.
np.random.shuffle(x)
Е. Массив будет перетасовываться вдоль первой оси по желанию. Однако использованиеrandom.shuffle(x)
приведет к повторениям. Вы можете проверить это, запустивlen(np.unique(x))
после перетасовки, что дает 10 (как и ожидалось),np.random.shuffle()
но только около 5 при использованииrandom.shuffle()
.источник