Нашли ошибку?
Скачать чистый
урок 2 из 4≈ 15 минупражнения: 0 из 4

Распределения и гистограммы

Нормальное и равномерное распределения — рост людей и время ожидания; гистограмма np.histogram — сколько значений в каждом интервале; np.bincount — сколько раз каждое целое.

Python запустится при первом выполнении

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
[ ]Упражнение 1Баллы экзамена решено

Создайте генератор с seed 10 и смоделируйте баллы 500 участников экзамена: нормальное распределение со средним 65 и отклонением 12. Сохраните их в exam, а в high_share — долю участников, набравших больше 80.

rng = ...
exam = ...
high_share = ...

Равномерное распределение

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.  ]
[ ]Упражнение 2Долгое ожидание решено

Создайте генератор с seed 8 и смоделируйте 500 ожиданий автобуса — равномерно от 0 до 10 минут. Сохраните их в waits, а в long_share — долю ожиданий дольше 7 минут.

rng = ...
waits = ...
long_share = ...

Гистограмма: np.histogram

Чтобы увидеть распределение, значения раскладывают по интервалам и считают, сколько попало в каждый. Это гистограмма (histogram). np.histogram(a, bins=…) возвращает два массива: сколько значений в каждом интервале и сами границы интервалов. В bins можно передать список границ:

[ ]Рост по интервалам в 10 см
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 см попадёт в следующий. Исключение — последний интервал, у него включены обе границы. Можно передать и число — сколько интервалов равной ширины сделать между минимумом и максимумом.

[ ]Упражнение 3Баллы по интервалам решено

Разложите баллы exam по интервалам 0–40, 40–60, 60–80, 80–100 и сохраните в counts число участников в каждом (четыре числа).

counts = ...

Вопрос

В bins передали 5 границ: [0, 25, 50, 75, 100]. Сколько чисел будет в массиве с количествами?

Сколько раз каждое целое: np.bincount

Для целых чисел есть способ проще: np.bincount(a) возвращает массив, где на месте k стоит, сколько раз в a встретилось число k. Удобно для кубиков — индекс массива и есть выпавшее число:

[ ]600 бросков кубика
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:].

[ ]Упражнение 4Какая грань чаще решено

Создайте генератор с seed 4, сделайте 1200 бросков кубика и сохраните в faces число выпадений каждой грани от 1 до 6 (шесть чисел), а в top_face — грань, выпавшую чаще всех.

rolls = ...
faces = ...
top_face = ...

Итоги

  • rng.normal(loc, scale, size) — нормальное распределение: значения теснятся около среднего.
  • rng.uniform(a, b, size) — равномерно между a и b.
  • counts, edges = np.histogram(a, bins=…) — число значений в каждом интервале и границы.
  • np.bincount(a) — сколько раз встретилось каждое целое от 0 до максимума; работает только с целыми неотрицательными числами.

Подробнее в справочнике

Нашли ошибку?