Python Random Array из 0 и 1
Я хочу случайным образом произвести array
из n
одни и m
нули.
Я думал об этом решении:
- произвести массив
np.ones
) - создать массив нулей (
np.zeros
) - объединить их в один массив (
np.hstack
) - перемешать полученный массив (
np.random.shuffle
)
Кажется, не является естественным решением. Некоторые питонские идеи?
4 ответа
Ваше решение кажется разумным. В нем точно указано, что он делает, и делает это четко.
Давайте сравним вашу реализацию:
a = np.hstack((np.ones(n), np.zeros(m)))
np.random.shuffle(a)
... с очевидной альтернативой:
a = np.ones(n+m)
a[:m] = 0
np.random.shuffle(a)
Это может сэкономить немного времени, не выделяя и не перемещая фрагменты данных, но это требует немного больше мысли, чтобы понять.
И делать это в Python, а не в NumPy:
a = np.array([1]*n + [0]*m)
np.random.shuffle(a)
... может быть немного более кратким, но он выглядит менее идиоматически NumPy (так же, как np.array([1]*n)
менее идиоматичен, чем np.ones(n)
), и это будет медленнее и использовать больше памяти без веской причины. (Вы можете улучшить память, используя np.fromiter
, но тогда это довольно явно не будет более кратким.)
Конечно, если вы делаете это более одного раза, реальный ответ состоит в том, чтобы выделить это в функцию. Тогда название функции объяснит, что она делает, и почти любое решение, которое не слишком мучительно, будет довольно легко понять...
Я бы сделал массив из n единиц и m нулей, как
a = np.array([1] * n + [0] * m)
Тогда я бы позвонил np.random.shuffle()
в теме.
Я думаю, что ваше решение подходит, потому что оно читаемо и питонно. Вы не сказали, являются ли память или производительность соображениями. Возможно, что np.random.shuffle так же хорош, как O(m + n), но другие ответы предполагают, что он делает больше, чем один проход, чтобы перемешать значения. Вы можете сделать это в O (m + n) только с одним проходом и без затрат памяти, как это:
import random
m = 600 # zeros
n = 400 # ones
result = []
while m + n > 0:
if (m > 0 and random.random() < float(m)/float(m + n)):
result.append(0)
m -= 1
else:
result.append(1)
n -= 1
Использование numpy.random.permutation
:
a = numpy.random.permutation([1] * n + [0] * m)
или, используя массивы вместо исходного списка:
a = numpy.random.permutation(numpy.concatenate(np.ones(n), np.zeros(m)))
(Я не знаю достаточно о numpy
прокомментировать разницу между concatenate
а также hstack
; похоже, они дают одинаковые результаты.)