80 баллов по физике — это много или мало? Зависит от того, как написали остальные. Если по физике средний балл 67 и все близко к нему, 80 — отличный результат; если средний 80 — обычный. Чтобы сравнивать значения из разных столбцов, их нормализуют — приводят к общему масштабу. Благодаря транслированию это одна строка для всей таблицы.
import numpy as np
scores = np.loadtxt("data/scores.csv", delimiter=",", skiprows=1, usecols=(1, 2, 3, 4, 5))
print(np.round(scores.mean(axis=0), 1))
print(np.round(scores.std(axis=0), 1))[67.8 66.8 69. 69.7 66. ] [11.7 12.6 12.2 12.6 12.1]
z-оценка
z-оценка (z-score, стандартизация) показывает, на сколько стандартных отклонений значение выше или ниже среднего: z = (x − среднее) / std. z = 0 — ровно средне, z = 1 — на одно отклонение лучше, z = −2 — заметно хуже. После стандартизации у данных среднее 0 и std 1, в каких бы единицах они ни были.
math_scores = scores[:, 0]
z_math = (math_scores - math_scores.mean()) / math_scores.std()
print(np.round(z_math[:5], 2))
print(round(z_math.mean(), 6) == 0, round(z_math.std(), 6)) # round — чтобы крошечная погрешность не мешала сравнению[ 0.02 0.19 -0.58 0.7 0.87] True 1.0
Сохраните в z_phys z-оценки баллов по физике (столбец 1), а в best_phys — индекс студента с самой высокой
z-оценкой.
scores[:, 1]; формула — (x - x.mean()) / x.std().Заготовка упражнения обновилась с тех пор, как вы сохранили свой код.
Вернуть заготовку? Ваш код в этом упражнении будет удалён.
z_phys = ...
best_phys = ...Упражнение пока не решено, поэтому для ячеек ниже выполнено эталонное решение — ваш код не изменён.
phys = scores[:, 1]
z_phys = (phys - phys.mean()) / phys.std()
best_phys = z_phys.argmax()Вся таблица сразу
Средние и std по столбцам — строки формы (5,), и они транслируются на таблицу 30 × 5. Каждый столбец
стандартизуется по своим среднему и разбросу:
z_demo = (scores - scores.mean(axis=0)) / scores.std(axis=0)
print(z_demo.shape)
print(np.round(z_demo[:2], 1))
print(np.allclose(z_demo.mean(axis=0), 0), np.allclose(z_demo.std(axis=0), 1))(30, 5) [[ 0. -1.4 -0.1 1. 1.2] [ 0.2 -0.1 -0.1 0.6 1.7]] True True
Чтобы проверить, что средние стали нулями, а отклонения — единицами, используем np.allclose(a, b): она
отвечает, близки ли все значения a к b. Сравнивать дробные результаты через == нельзя — из-за
приближённого хранения там может оказаться 0.0000000000000001 вместо 0.
Сохраните в z таблицу z-оценок: каждый столбец scores стандартизован по своему предмету.
axis=0.(scores - scores.mean(axis=0)) / scores.std(axis=0).Заготовка упражнения обновилась с тех пор, как вы сохранили свой код.
Вернуть заготовку? Ваш код в этом упражнении будет удалён.
z = ...Упражнение пока не решено, поэтому для ячеек ниже выполнено эталонное решение — ваш код не изменён.
z = (scores - scores.mean(axis=0)) / scores.std(axis=0)Какими станут среднее и стандартное отклонение каждого столбца после стандартизации?
От 0 до 1
Другой способ — растянуть значения на отрезок от 0 до 1 (min-max-нормализация): минимум становится 0, максимум — 1, остальное — пропорционально между ними: (x − min) / (max − min).
Сохраните в scaled таблицу, где баллы каждого предмета приведены к отрезку от 0 до 1 по минимуму и максимуму
этого предмета.
min(axis=0) и max(axis=0).(scores - lo) / (hi - lo), где lo и hi — эти строки.Заготовка упражнения обновилась с тех пор, как вы сохранили свой код.
Вернуть заготовку? Ваш код в этом упражнении будет удалён.
scaled = ...Упражнение пока не решено, поэтому для ячеек ниже выполнено эталонное решение — ваш код не изменён.
lo = scores.min(axis=0)
hi = scores.max(axis=0)
scaled = (scores - lo) / (hi - lo)Общий рейтинг
Когда предметы в одном масштабе, их можно честно усреднять: средняя z-оценка студента показывает, насколько он в целом выше группы, и сложные предметы не «топят» результат.
Сохраните в overall среднюю z-оценку каждого студента по пяти предметам (таблица z из упражнения выше),
а в top_student — индекс студента с наибольшей средней z-оценкой.
z.mean(axis=1).Заготовка упражнения обновилась с тех пор, как вы сохранили свой код.
Вернуть заготовку? Ваш код в этом упражнении будет удалён.
overall = ...
top_student = ...Упражнение пока не решено, поэтому для ячеек ниже выполнено эталонное решение — ваш код не изменён.
overall = z.mean(axis=1)
top_student = overall.argmax()Итоги
- z = (x − среднее) / std: сравнимые значения из разных шкал; после неё среднее 0, std 1.
- min-max: (x − min) / (max − min) — отрезок от 0 до 1.
- Для таблицы — агрегаты по
axis=0транслируются на все строки. - Разность — в скобки: деление выполняется раньше вычитания.