integers и random выдают все значения одинаково часто. В жизни так бывает редко: рост людей чаще около
среднего, чем 150 или 195 см. Как часто встречаются разные значения, описывает распределение
(distribution).
Нормальное распределение
Рост, вес, ошибки измерений похожи на нормальное распределение: большинство значений около среднего, а чем
дальше от него, тем реже. Задаётся двумя числами: средним loc и стандартным отклонением scale:
import numpy as np
rng = np.random.default_rng(1)
heights = rng.normal(loc=170, scale=8, size=1000)
print(np.round(heights[:6], 1))
print(round(heights.mean(), 1), round(heights.std(), 1))[172.8 176.6 172.6 159.6 177.2 173.6] 169.6 7.9
Среднее и отклонение получились близкими к заданным 170 и 8, но не точно — это случайная выборка. У нормального распределения примерно 68 % значений лежат в пределах одного отклонения от среднего:
print(((heights > 162) & (heights < 178)).mean())0.699
Создайте генератор с seed 10 и смоделируйте баллы 500 участников экзамена: нормальное распределение со средним
65 и отклонением 12. Сохраните их в exam, а в high_share — долю участников, набравших больше 80.
rng.normal(loc=65, scale=12, size=500).exam > 80.Заготовка упражнения обновилась с тех пор, как вы сохранили свой код.
Вернуть заготовку? Ваш код в этом упражнении будет удалён.
rng = ...
exam = ...
high_share = ...Упражнение пока не решено, поэтому для ячеек ниже выполнено эталонное решение — ваш код не изменён.
rng = np.random.default_rng(10)
exam = rng.normal(loc=65, scale=12, size=500)
high_share = (exam > 80).mean()Равномерное распределение
rng.uniform(a, b, size=n) — дробные числа, которые с равной вероятностью попадают куда угодно между a и b.
Так можно моделировать, например, время ожидания автобуса, который ходит раз в 10 минут:
rng = np.random.default_rng(2)
waits_demo = rng.uniform(0, 10, size=5)
print(np.round(waits_demo, 2))[2.62 2.98 8.14 0.92 6. ]
Создайте генератор с seed 8 и смоделируйте 500 ожиданий автобуса — равномерно от 0 до 10 минут. Сохраните
их в waits, а в long_share — долю ожиданий дольше 7 минут.
rng.uniform(0, 10, size=500).Заготовка упражнения обновилась с тех пор, как вы сохранили свой код.
Вернуть заготовку? Ваш код в этом упражнении будет удалён.
rng = ...
waits = ...
long_share = ...Упражнение пока не решено, поэтому для ячеек ниже выполнено эталонное решение — ваш код не изменён.
rng = np.random.default_rng(8)
waits = rng.uniform(0, 10, size=500)
long_share = (waits > 7).mean()Гистограмма: np.histogram
Чтобы увидеть распределение, значения раскладывают по интервалам и считают, сколько попало в каждый. Это
гистограмма (histogram). np.histogram(a, bins=…) возвращает два массива: сколько значений в каждом
интервале и сами границы интервалов. В bins можно передать список границ:
counts_demo, edges_demo = np.histogram(heights, bins=[140, 150, 160, 170, 180, 190, 200, 210])
print(counts_demo)
print(edges_demo)
print(counts_demo.sum())[ 7 104 401 401 81 5 1] [140 150 160 170 180 190 200 210] 1000
Интервал включает левую границу и не включает правую — [150, 160): рост ровно 160 см попадёт в следующий.
Исключение — последний интервал, у него включены обе границы. Можно передать и число — сколько интервалов
равной ширины сделать между минимумом и максимумом.
Разложите баллы exam по интервалам 0–40, 40–60, 60–80, 80–100 и сохраните в counts число участников
в каждом (четыре числа).
np.histogram(exam, bins=[0, 40, 60, 80, 100]).counts, edges = np.histogram(...).Заготовка упражнения обновилась с тех пор, как вы сохранили свой код.
Вернуть заготовку? Ваш код в этом упражнении будет удалён.
counts = ...Упражнение пока не решено, поэтому для ячеек ниже выполнено эталонное решение — ваш код не изменён.
counts, edges = np.histogram(exam, bins=[0, 40, 60, 80, 100])В bins передали 5 границ: [0, 25, 50, 75, 100]. Сколько чисел будет в массиве с количествами?
Сколько раз каждое целое: np.bincount
Для целых чисел есть способ проще: np.bincount(a) возвращает массив, где на месте k стоит, сколько раз
в a встретилось число k. Удобно для кубиков — индекс массива и есть выпавшее число:
rolls_demo = np.random.default_rng(42).integers(1, 7, size=600)
print(np.bincount(rolls_demo))
print(np.bincount(rolls_demo)[1:])[ 0 109 98 97 93 108 95] [109 98 97 93 108 95]
На месте 0 стоит 0: ноль на кубике не выпадает. Чтобы оставить только грани 1–6, берут срез [1:].
Создайте генератор с seed 4, сделайте 1200 бросков кубика и сохраните в faces число выпадений каждой грани
от 1 до 6 (шесть чисел), а в top_face — грань, выпавшую чаще всех.
np.bincount(rolls)[1:] — без нулевой грани.Заготовка упражнения обновилась с тех пор, как вы сохранили свой код.
Вернуть заготовку? Ваш код в этом упражнении будет удалён.
rolls = ...
faces = ...
top_face = ...Упражнение пока не решено, поэтому для ячеек ниже выполнено эталонное решение — ваш код не изменён.
rolls = np.random.default_rng(4).integers(1, 7, size=1200)
faces = np.bincount(rolls)[1:]
top_face = faces.argmax() + 1Итоги
rng.normal(loc, scale, size)— нормальное распределение: значения теснятся около среднего.rng.uniform(a, b, size)— равномерно междуaиb.counts, edges = np.histogram(a, bins=…)— число значений в каждом интервале и границы.np.bincount(a)— сколько раз встретилось каждое целое от 0 до максимума; работает только с целыми неотрицательными числами.