Туристический сайт просит короткую справку: чем климат Сочи отличается от климата Новосибирска. «В Сочи
теплее» знают все — нужны числа. В файле data/weather.csv — погода пяти городов за каждый день 2025 года.
Новых методов в проекте нет.
import pandas as pd
weather = pd.read_csv("data/weather.csv", parse_dates=["date"])
weather.head(3)| date | city | temp_min | temp_max | precip_mm | wind_ms | |
|---|---|---|---|---|---|---|
| 0 | 2025-01-01 | Москва | -9.9 | -3.2 | 0.0 | 1.9 |
| 1 | 2025-01-02 | Москва | -9.7 | -3.2 | 0.0 | 2.3 |
| 2 | 2025-01-03 | Москва | -9.0 | -3.7 | 0.0 | 5.2 |
Шаг 1. Подготовка
В данных есть пропуски: датчики иногда не передавали показания. Отдельного столбца со средней температурой дня нет — посчитаем её как среднее между ночным минимумом и дневным максимумом.
Сохраните в gaps число пропусков в каждом столбце таблицы weather. Добавьте столбец temp_avg —
полусумму temp_min и temp_max. В no_avg сохраните число пропусков в новом столбце.
weather.isna().sum().(weather["temp_min"] + weather["temp_max"]) / 2 — скобки обязательны: деление выполняется раньше сложения.Заготовка упражнения обновилась с тех пор, как вы сохранили свой код.
Вернуть заготовку? Ваш код в этом упражнении будет удалён.
gaps = ...
# добавьте в weather столбец temp_avg
no_avg = ...Упражнение пока не решено, поэтому для ячеек ниже выполнено эталонное решение — ваш код не изменён.
gaps = weather.isna().sum()
weather["temp_avg"] = (weather["temp_min"] + weather["temp_max"]) / 2
no_avg = weather["temp_avg"].isna().sum()Пропусков в temp_avg пять: три дня без минимума и два без максимума. Арифметика с пропуском даёт
пропуск — и это честно: если одно из двух чисел неизвестно, неизвестно и их среднее. Пять дней из 1825 на итоги
почти не влияют; оставим их пропусками — mean и std их не учитывают.
Шаг 2. Средняя температура и разброс
Сохраните в sochi и nsk строки Сочи и Новосибирска — независимыми копиями (.copy()): дальше мы будем
добавлять в них столбцы. По столбцу temp_avg посчитайте среднее (sochi_mean, nsk_mean) и стандартное
отклонение (sochi_std, nsk_std).
weather[weather["city"] == "Сочи"].copy().sochi["temp_avg"].mean() и sochi["temp_avg"].std().Заготовка упражнения обновилась с тех пор, как вы сохранили свой код.
Вернуть заготовку? Ваш код в этом упражнении будет удалён.
sochi = ...
nsk = ...
sochi_mean = ...
nsk_mean = ...
sochi_std = ...
nsk_std = ...Упражнение пока не решено, поэтому для ячеек ниже выполнено эталонное решение — ваш код не изменён.
sochi = weather[weather["city"] == "Сочи"].copy()
nsk = weather[weather["city"] == "Новосибирск"].copy()
sochi_mean = sochi["temp_avg"].mean()
nsk_mean = nsk["temp_avg"].mean()
sochi_std = sochi["temp_avg"].std()
nsk_std = nsk["temp_avg"].std()Средняя температура года — 15 градусов против 1.6. Но различие не только в среднем: разброс в Новосибирске вдвое больше. Там и теплее, и холоднее, чем можно подумать, глядя на «плюс полтора в среднем».
Шаг 3. Какие дни бывают
Среднее скрывает, из чего оно сложилось. Разобьём дни по дневному максимуму на типы.
Добавьте в nsk и в sochi столбец kind — тип дня по temp_max с границами bins и подписями names.
Сохраните в nsk_kinds и sochi_kinds доли дней каждого типа по порядку шкалы.
pd.cut(nsk["temp_max"], bins=bins, labels=names).nsk["kind"].value_counts(normalize=True).sort_index().Заготовка упражнения обновилась с тех пор, как вы сохранили свой код.
Вернуть заготовку? Ваш код в этом упражнении будет удалён.
bins = [-50, 0, 15, 25, 50]
names = ["ниже нуля", "прохладно", "тепло", "жарко"]
# добавьте столбец kind в nsk и в sochi
nsk_kinds = ...
sochi_kinds = ...Упражнение пока не решено, поэтому для ячеек ниже выполнено эталонное решение — ваш код не изменён.
bins = [-50, 0, 15, 25, 50]
names = ["ниже нуля", "прохладно", "тепло", "жарко"]
nsk["kind"] = pd.cut(nsk["temp_max"], bins=bins, labels=names)
sochi["kind"] = pd.cut(sochi["temp_max"], bins=bins, labels=names)
nsk_kinds = nsk["kind"].value_counts(normalize=True).sort_index()
sochi_kinds = sochi["kind"].value_counts(normalize=True).sort_index()print(nsk_kinds.round(2))
print(sochi_kinds.round(2))kind ниже нуля 0.41 прохладно 0.34 тепло 0.18 жарко 0.07 Name: proportion, dtype: float64 kind ниже нуля 0.00 прохладно 0.38 тепло 0.49 жарко 0.14 Name: proportion, dtype: float64
В Новосибирске 41 % дней в году — с дневным максимумом ниже нуля. В Сочи таких дней нет вовсе, зато каждый седьмой день — жарче 25 градусов. При этом жаркие дни есть и в Новосибирске — 7 %.
Шаг 4. Осадки
Посчитайте для каждого города долю дней с осадками (precip_mm больше нуля) — sochi_rainy и nsk_rainy —
и сумму осадков за год — sochi_total и nsk_total. В sochi_heavy сохраните число дней в Сочи, когда выпало
10 мм и больше.
sochi["precip_mm"] > 0; сумма — sochi["precip_mm"].sum().sochi["precip_mm"] >= 10.Заготовка упражнения обновилась с тех пор, как вы сохранили свой код.
Вернуть заготовку? Ваш код в этом упражнении будет удалён.
sochi_rainy = ...
nsk_rainy = ...
sochi_total = ...
nsk_total = ...
sochi_heavy = ...Упражнение пока не решено, поэтому для ячеек ниже выполнено эталонное решение — ваш код не изменён.
sochi_rainy = (sochi["precip_mm"] > 0).mean()
nsk_rainy = (nsk["precip_mm"] > 0).mean()
sochi_total = sochi["precip_mm"].sum()
nsk_total = nsk["precip_mm"].sum()
sochi_heavy = (sochi["precip_mm"] >= 10).sum()Неожиданный результат: дней с осадками в Сочи меньше (30 % против 40 %), а воды выпадает в полтора раза больше. Дожди там реже, но сильнее: 29 дней в году — с осадками от 10 мм.
Шаг 5. Лето и зима
Годовая амплитуда — разность средних температур самого тёплого и самого холодного месяца. Это главная характеристика континентальности климата.
Добавьте в nsk столбец month — номер месяца. Сохраните в january и july среднюю temp_avg января
и июля, а в amplitude — их разность (июль минус январь).
nsk["date"].dt.month.nsk.loc[nsk["month"] == 1, "temp_avg"].mean().Заготовка упражнения обновилась с тех пор, как вы сохранили свой код.
Вернуть заготовку? Ваш код в этом упражнении будет удалён.
# добавьте в nsk столбец month
january = ...
july = ...
amplitude = ...Упражнение пока не решено, поэтому для ячеек ниже выполнено эталонное решение — ваш код не изменён.
nsk["month"] = nsk["date"].dt.month
january = nsk.loc[nsk["month"] == 1, "temp_avg"].mean()
july = nsk.loc[nsk["month"] == 7, "temp_avg"].mean()
amplitude = july - januaryШаг 6. Оттепели в Москве
Напоследок — вопрос о необычных днях. Оттепель — зимний день, когда дневная температура поднимается выше нуля.
Сохраните в winter зимние дни таблицы moscow — декабрь, январь и февраль. В thaws — зимние дни
с temp_max выше нуля: только столбцы date и temp_max. В warmest_date — дату самого тёплого зимнего дня.
moscow["date"].dt.month.isin([12, 1, 2]).winter.loc[winter["temp_max"] > 0, ["date", "temp_max"]]; дата рекорда — winter.loc[winter["temp_max"].idxmax(), "date"].Заготовка упражнения обновилась с тех пор, как вы сохранили свой код.
Вернуть заготовку? Ваш код в этом упражнении будет удалён.
moscow = weather[weather["city"] == "Москва"]
winter = ...
thaws = ...
warmest_date = ...Упражнение пока не решено, поэтому для ячеек ниже выполнено эталонное решение — ваш код не изменён.
moscow = weather[weather["city"] == "Москва"]
winter = moscow[moscow["date"].dt.month.isin([12, 1, 2])]
thaws = winter.loc[winter["temp_max"] > 0, ["date", "temp_max"]]
warmest_date = winter.loc[winter["temp_max"].idxmax(), "date"]Справка
print("Средняя температура: Сочи", round(sochi_mean, 1), "· Новосибирск", round(nsk_mean, 1))
print("Разброс (std): Сочи", round(sochi_std, 1), "· Новосибирск", round(nsk_std, 1))
print("Осадки за год, мм: Сочи", round(sochi_total), "· Новосибирск", round(nsk_total))
print("Дней с осадками: Сочи", round(sochi_rainy * 100), "% · Новосибирск", round(nsk_rainy * 100), "%")
print("Годовая амплитуда в Новосибирске:", round(amplitude, 1), "градуса")
print("Оттепелей в Москве за зимние месяцы:", len(thaws))Средняя температура: Сочи 15.0 · Новосибирск 1.6 Разброс (std): Сочи 6.3 · Новосибирск 14.0 Осадки за год, мм: Сочи 795 · Новосибирск 520 Дней с осадками: Сочи 30 % · Новосибирск 40 % Годовая амплитуда в Новосибирске: 40.1 градуса Оттепелей в Москве за зимние месяцы: 5
Выводы
- В Сочи в среднем на 13 градусов теплее, и температура вдвое стабильнее.
- В Новосибирске 41 % дней — с морозом даже днём; в Сочи таких дней нет.
- Осадков в Сочи больше в полтора раза, хотя дождливых дней меньше: дожди реже, но сильнее.
- Годовая амплитуда в Новосибирске — 40 градусов: от −17.6 в январе до +22.5 в июле.
- В Москве за три зимних месяца 2025 года (январь, февраль и декабрь) было пять оттепелей — 6 % зимних дней.
Мы сравнили два города — и для каждого писали одни и те же строки дважды. Городов в файле пять; для пяти пришлось бы писать впятеро больше. Следующий модуль — о том, как посчитать всё это по каждому городу одной командой.