Модуль numpy.random
Модуль numpy.random отвечает за генерацию случайных чисел и выборок из различных распределений. Начиная с NumPy 1.17 рекомендуемый способ работы — через np.random.default_rng(): он возвращает объект Generator с современным алгоритмом PCG64 и явным управлением состоянием.
Старый интерфейс (np.random.rand, np.random.randint и т.п.) всё ещё работает, но в новом коде лучше пользоваться Generator.
Зачем нужно
Тестирование алгоритмов. Сгенерировать «шумные» данные, имитирующие измерения с датчиков.
Машинное обучение. Случайно перемешать выборку, инициализировать веса, разделить train/test.
Симуляция. Метод Монте-Карло, моделирование радио-помех, разброса параметров компонентов.
Игры и тесты. Случайные команды для робота, проверка устойчивости системы к шуму.
Пример 1. Создание генератора с seed
Передача seed делает результаты воспроизводимыми — это важно для отладки и публикаций.
import numpy as np
rng = np.random.default_rng(seed=42)
print(rng.random(3))
rng2 = np.random.default_rng(seed=42)
print(rng2.random(3)) # те же числа
[0.77395605 0.43887844 0.85859792]
[0.77395605 0.43887844 0.85859792]
Если seed не передан — генератор инициализируется системной энтропией, и результаты будут разными при каждом запуске.
Пример 2. Равномерное распределение
random() возвращает числа в [0, 1). Для произвольного диапазона — uniform.
import numpy as np
rng = np.random.default_rng(0)
pwm = rng.uniform(0, 255, size=5) # имитация ШИМ
print(np.round(pwm, 1))
[161.7 39.1 213.8 215.9 168.4]
Пример 3. Целые числа
integers(low, high, size) — целые из полуинтервала [low, high). Если нужно включить границу — endpoint=True.
import numpy as np
rng = np.random.default_rng(1)
dice = rng.integers(1, 7, size=10) # игральная кость
pins = rng.integers(2, 14, size=4) # случайные пины Arduino
print(dice)
print(pins)
[5 6 1 1 2 6 1 4 6 2]
[10 7 3 8]
Пример 4. Нормальное распределение
normal(loc, scale, size) — гауссово распределение со средним loc и стандартным отклонением scale. Хороший шум для имитации погрешности датчика.
import numpy as np
rng = np.random.default_rng(2)
true_temp = 23.5
noisy = rng.normal(loc=true_temp, scale=0.2, size=8)
print(np.round(noisy, 2))
print("mean:", np.round(noisy.mean(), 3))
[23.42 23.41 23.6 23.62 23.35 23.16 23.5 23.78]
mean: 23.48
Пример 5. Случайный выбор (choice)
Выборка элементов из массива — с возвращением или без, с весами.
import numpy as np
rng = np.random.default_rng(3)
commands = np.array(['forward', 'back', 'left', 'right', 'stop'])
# 5 случайных команд с возвращением
seq = rng.choice(commands, size=5)
print(seq)
# 3 уникальных команды (без возврата)
uniq = rng.choice(commands, size=3, replace=False)
print(uniq)
# С весами — чаще "forward"
weighted = rng.choice(commands, size=6,
p=[0.5, 0.1, 0.15, 0.15, 0.1])
print(weighted)
['stop' 'forward' 'left' 'forward' 'back']
['right' 'stop' 'back']
['forward' 'forward' 'right' 'forward' 'stop' 'left']
Пример 6. Перемешивание (shuffle и permutation)
shuffle перемешивает на месте, permutation возвращает копию.
import numpy as np
rng = np.random.default_rng(4)
data = np.arange(10)
shuffled = rng.permutation(data)
print(shuffled)
print(data) # исходный массив не тронут
rng.shuffle(data)
print(data) # теперь перемешан на месте
[9 5 0 8 7 3 4 1 2 6]
[0 1 2 3 4 5 6 7 8 9]
[3 0 6 4 5 7 9 8 1 2]
Пример 7. Имитация шумного сигнала с датчика
Соберём «измерения» с дрейфом, шумом и редкими выбросами.
import numpy as np
rng = np.random.default_rng(5)
t = np.arange(20)
drift = 0.05 * t # медленный дрейф
noise = rng.normal(0, 0.3, size=20) # обычный шум
spikes = rng.choice([0, 5], size=20, p=[0.9, 0.1]) # 10% выбросов
signal = 25.0 + drift + noise + spikes
print(np.round(signal[:10], 2))
[25. 25.31 24.91 30.55 25.41 25.66 30.51 25.91 30.6 26.04]
Пример 8. Многомерные массивы
Любая функция принимает size в виде кортежа — получится массив нужной формы.
import numpy as np
rng = np.random.default_rng(6)
matrix = rng.normal(0, 1, size=(3, 4))
print(np.round(matrix, 2))
[[ 0.94 -1.32 0.65 0.65]
[-0.42 -1.42 -0.42 -0.34]
[ 0.36 -0.45 -0.4 0.4 ]]
Подводные камни
Старый vs новый API.
np.random.randиnp.random.seed— устаревший глобальный интерфейс. В новом коде используйтеrng = np.random.default_rng(seed)и методы на нём.Несравнимые seed-ы. Один и тот же seed в старом и новом API даст разные последовательности — это нормально.
Воспроизводимость в потоках. Не делите один
Generatorмежду потоками. Используйтеrng.spawn(n)для дочерних генераторов.integers vs randint. В новом API метод называется
integers, и по умолчанию верхняя граница НЕ включается, как и в старомrandint— но не путайте сrandom_integers(устаревшая, включала границу).Не используйте для криптографии. PCG64 — быстрый, но не криптостойкий. Для секретов — модуль
secrets.
См. также
Создание массивов NumPy — создание массивов
Векторизация в NumPy — векторные операции
Универсальные функции (ufunc) — ufunc
Примечание
Лицензия и источники
Техническое описание адаптировано из официальной документации NumPy (https://numpy.org/doc/stable/), доступной под BSD-3-Clause License. Перевод на русский, примеры и пояснения — © AlashEd Wiki.