Три метеостанции — в центре, в аэропорту и в лесу за городом — прислали данные за февраль 2025 года. В файлах есть пропуски: датчик в аэропорту молчал пять дней. Задача — собрать общую картину: где и когда было холоднее, насколько центр теплее окраин, и сохранить недельный отчёт.
Шаг 1. Одна таблица
Загрузите три файла data/station_center.csv, data/station_airport.csv, data/station_forest.csv и соберите
в temps таблицу температур (столбец 1 каждого файла): строка — станция в этом порядке, столбец — день.
В gaps сохраните число пропусков у каждой станции.
np.genfromtxt(путь, delimiter=",", skip_header=1); можно сразу usecols=1.np.stack([...]); пропуски по станции — сумма маски np.isnan(temps) по axis=1.Заготовка упражнения обновилась с тех пор, как вы сохранили свой код.
Вернуть заготовку? Ваш код в этом упражнении будет удалён.
import numpy as np
temps = ...
gaps = ...Упражнение пока не решено, поэтому для ячеек ниже выполнено эталонное решение — ваш код не изменён.
import numpy as np
center = np.genfromtxt("data/station_center.csv", delimiter=",", skip_header=1)
airport = np.genfromtxt("data/station_airport.csv", delimiter=",", skip_header=1)
forest = np.genfromtxt("data/station_forest.csv", delimiter=",", skip_header=1)
temps = np.stack([center[:, 1], airport[:, 1], forest[:, 1]])
gaps = np.isnan(temps).sum(axis=1)Шаг 2. Заполнить пропуски соседями
Средняя по всему месяцу — плохая замена для одного дня: погода в феврале менялась от −9 до +3. Гораздо точнее взять показания других станций в тот же день — станции стоят недалеко друг от друга, и погода у них меняется вместе.
Сохраните в day_mean среднюю температуру каждого дня по тем станциям, которые его записали, а в filled —
таблицу temps, где каждый пропуск заменён средней этого дня.
np.nanmean(temps, axis=0): получится 28 чисел.np.where(np.isnan(temps), day_mean, temps) — day_mean формы (28,) транслируется на каждую строку.Заготовка упражнения обновилась с тех пор, как вы сохранили свой код.
Вернуть заготовку? Ваш код в этом упражнении будет удалён.
day_mean = ...
filled = ...Упражнение пока не решено, поэтому для ячеек ниже выполнено эталонное решение — ваш код не изменён.
day_mean = np.nanmean(temps, axis=0)
filled = np.where(np.isnan(temps), day_mean, temps)Первая проверка — пропусков не осталось, а средние станций стали числами:
print(np.isnan(filled).sum(), "пропусков")
print(np.round(temps.mean(axis=1), 2))
print(np.round(filled.mean(axis=1), 2))0 пропусков [ nan nan -6.08] [-3.07 -4.49 -6.08]
Способ не идеален: центр обычно теплее соседей, и его единственный пропуск заполнен чуть холоднее, чем было на самом деле. Но один день из 28 почти не сдвигает средние — и это честнее, чем ноль или средняя за месяц.
Шаг 3. По неделям
28 дней — ровно четыре недели. Таблицу 3 × 28 можно превратить в трёхмерную 3 × 4 × 7 — стопку из трёх таблиц, как все исходы трёх кубиков в модуле о случайных числах. Вот тот же приём на маленьком примере: два ряда по 14 дней (две недели) становятся стопкой 2 × 2 × 7 — ряд, неделя, день недели:
sample = np.arange(1, 29).reshape(2, 14) # 2 ряда по 14 дней — две недели
sample_weeks = sample.reshape(2, 2, 7) # ряд → неделя → день недели
print(sample_weeks.shape)
print(sample_weeks[0]) # первый ряд: 2 строки-недели по 7 дней(2, 2, 7) [[ 1 2 3 4 5 6 7] [ 8 9 10 11 12 13 14]]
reshape раскладывает каждую строку по неделям по порядку дней, ничего не перемешивая. Какую ось сворачивать
для недельной средней, решите по смыслу осей: у таблицы станций ось 0 — станция, ось 1 — неделя, ось 2 — день.
Сохраните в weekly таблицу 3 × 4 — среднюю температуру каждой станции за каждую неделю (по filled), а в
coldest_week — номер самой холодной недели (от 1 до 4) по средней трёх станций.
(3, 4, 7); средняя за неделю сворачивает дни недели.weekly.mean(axis=0); номер недели — argmin плюс один.Заготовка упражнения обновилась с тех пор, как вы сохранили свой код.
Вернуть заготовку? Ваш код в этом упражнении будет удалён.
weekly = ...
coldest_week = ...Упражнение пока не решено, поэтому для ячеек ниже выполнено эталонное решение — ваш код не изменён.
weekly = filled.reshape(3, 4, 7).mean(axis=2)
coldest_week = weekly.mean(axis=0).argmin() + 1Шаг 4. Остров тепла
Город нагревает воздух: асфальт, дома, машины. Метеорологи называют это островом тепла.
Сохраните в station_avg среднюю температуру каждой станции за месяц (по filled), в island — насколько в
среднем центр теплее леса, а в thaw_days — число дней, когда хотя бы на одной станции было выше нуля.
filled[0] - filled[2]; её среднее — island.filled.max(axis=0) > 0.Заготовка упражнения обновилась с тех пор, как вы сохранили свой код.
Вернуть заготовку? Ваш код в этом упражнении будет удалён.
station_avg = ...
island = ...
thaw_days = ...Упражнение пока не решено, поэтому для ячеек ниже выполнено эталонное решение — ваш код не изменён.
station_avg = filled.mean(axis=1)
island = (filled[0] - filled[2]).mean()
thaw_days = (filled.max(axis=0) > 0).sum()Шаг 5. Отчёт в файл
Соберите в report таблицу 4 × 4: строка — неделя, первый столбец — номер недели (1–4), дальше средние центра,
аэропорта и леса. Сохраните её в файл data/weekly.csv через запятую, с одним знаком после точки.
weekly.T (4 × 3); номер недели — столбец np.arange(1, 5)[:, np.newaxis].np.hstack([...]) и np.savetxt("data/weekly.csv", report, delimiter=",", fmt="%.1f").Заготовка упражнения обновилась с тех пор, как вы сохранили свой код.
Вернуть заготовку? Ваш код в этом упражнении будет удалён.
report = ...Упражнение пока не решено, поэтому для ячеек ниже выполнено эталонное решение — ваш код не изменён.
report = np.hstack([np.arange(1, 5)[:, np.newaxis], weekly.T])
np.savetxt("data/weekly.csv", report, delimiter=",", fmt="%.1f")with open("data/weekly.csv") as f:
print(f.read())
print("центр теплее леса на", round(island, 1), "°C")1.0,-5.5,-6.7,-8.2 2.0,-4.9,-6.4,-7.6 3.0,-1.7,-3.1,-5.0 4.0,-0.2,-1.8,-3.5 центр теплее леса на 3.0 °C
Выводы
В центре города в феврале было в среднем на 3 °C теплее, чем в лесу, — остров тепла виден даже на трёх станциях. Самой холодной была первая неделя, к концу месяца на всех станциях потеплело примерно на 5 градусов. Пропуски не помешали: nan-функции посчитали итоги по тому, что есть, а для недельных таблиц мы заполнили дыры показаниями соседей — самым правдоподобным, что было под рукой.