2016-08-10 4 views
1

У меня есть массив с длиной n, я хочу случайным образом выбрать из него m элементов и перевернуть их значение. Каков наиболее эффективный способ?случайные значения flip m из массива

есть два случая, m=1 кейс специальный чехол. Это можно обсудить отдельно, и m=/=1.

Моя попытка:

import numpy as np 
n = 20 
m = 5 
#generate an array a 
a = np.random.randint(0,2,n)*2-1 
#random choose `m` element and flip it. 
for i in np.random.randint(0,n,m): 
    a[m]=-a[m] 

Пусть m десятки и n сотни.

+0

Определить эффективность. Кроме того, каковы приблизительные значения n и m? Самый эффективный метод для некоторых значений, возможно, не самый эффективный для других. – cammil

+0

@cammil См. Edit – buzhidao

ответ

3

Чтобы убедиться, что мы не переворачиваем один и тот же элемент дважды или даже больше, мы можем создавать уникальные индексы в этом диапазоне длин с np.random.choice, используя необязательный аргумент replace как False. Затем простое индексирование во входной массив и переключение в один проход должны дать нам желаемый результат. Таким образом, мы имели бы реализацию как так -

idx = np.random.choice(n,m,replace=False) 
a[idx] = -a[idx] 

Faster версия: Для более быстрой версии np.random_choice, я предложил бы читать на this post, что исследует с помощью np.argpartition для имитации идентичного поведения.

+0

'random.choice' verses' idx = np.random.randint (0, n, m) 'препятствовать тому, чтобы я выбрал сгенерировать один и тот же элемент. Отличная идея! – buzhidao

0

Вам нужно изменить индекс массива от m до i, чтобы фактически изменить значение. Результат:

import numpy as np 
n = 20 
m = 5 
#generate an array a 
a = np.random.randint(0,2,n)*2-1 
print(a) 
#random choose `i` element and flip it. 
for i in np.random.randint(0,n,m): 
    a[i] = -a[i] 

print(a) 

Мой выход:

[ 1 1 -1 -1 1 -1 -1 1 1 -1 -1 1 -1 1 1 1 1 -1 1 -1] 
[ 1 1 -1 -1 -1 -1 1 1 1 -1 -1 1 -1 -1 1 -1 1 -1 -1 -1] 
1

Вы можете сделать случайную перестановку индексов массива, сделайте первый m из них и переворачивать их значения:

a[np.random.permutation(range(len(a)))[:m]]*=-1 

Использование permutation подтвердите, что вы не выбираете один и тот же индекс дважды.

+0

Будут ли эти операции иметь разные индексы слева и справа? Я имею в виду: если мы выполняем 'a [random.randint()] = - a [random.randint()]', вероятно, мы не выполняем задачу, потому что с правой стороны 'random.randint()' будет работать второй раз таким образом, измените индекс. Если мы выполняем 'a [random.randint()] * = -1',' random.randint() 'запускается только один раз? – buzhidao

+0

«randint» будет работать только один раз. –

Смежные вопросы