Как перетасовать список с гауссовым распределением


Я хочу имитировать ошибку в сообщении (например: 1000010011 => 1010000011). Есть ли способ реализовать это в Python? Я попробовал следующее, что работает:

import random
a = "1011101101"
b = [el for el in a] # b = ['1', '0', '1', '1', '1', '0', '1', '1', '0', '1']
random.shuffle(b)
print b # b = ['0', '1', '1', '1', '0', '1', '1', '1', '1', '0']
random.shuffle(b, random.random)
print b # b = ['1', '1', '0', '1', '1', '0', '1', '0', '1', '1']

Я хотел бы, чтобы мое переупорядочение было нормально/гауссово распределено. Например:

import random
a = "1011101101"
b = [el for el in a] # b = ['1', '0', '1', '1', '1', '0', '1', '1', '0', '1']
random.shuffle(b,random.gauss(0.5,0.1))
print b # b = ['1', '0', '1', '1', '0', '0', '1', '1', '1', '1'] <= assume this is Gaussian distributed...
# OR
c = random.gauss(0.5,0.1)
random.shuffle(b,c)
print b # b = ['0', '0', '1', '1', '1', '0', '1', '1', '1', '1'] <= assume this is also Gaussian distributed...

Однако это не работает, и я получаю сообщение:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:Python27librandom.py", line 287, in shuffle
    j = int(random() * (i+1))
TypeError: 'float' object is not callable

Любое предложение/комментарий будут высоко оценены.

Спасибо

Примечание: Я прошу только о повторном заказе ошибки здесь(например: 1000010011 => 1010000011). Однако я также планирую имитировать пакетные ошибки(например: 1000010011 => 1011111011), единичные события (например: 1000010011 => 1000010011) и т. д.

Другой связанный вопрос: Python: моделирование ошибок двоичной строки

2 3

2 ответа:

Второй аргумент random.shuffle должен быть вызываемым, а не плавающим. Попробуйте:

random.shuffle(b, lambda:random.gauss(0.5,0.1))

Для ограничения интервала от 0 до 1 можно использовать

random.shuffle(b, lambda: max(0.0, min(1.0, random.gauss(0.5,0.1))))

(Спасибо @DSM)

Если вы педантичны, то приведенное выше ограничение на самом деле включает 1.0, что приведет к ошибке в random.shuffle. Фактически вы должны заменить 1.0 на самый большой поплавок меньше 1.0.

c = lambda: random.gauss(0.5,0.1)