Загрузка данных


import pandas as pd
import matplotlib.pyplot as plt
import urllib.request

# Настройка для корректного отображения
plt.rcParams['figure.figsize'] = [10, 5]

url = "https://anzhelian-edu.ru/api/edu/stend/export?id=e4798cd77c02716250&k=7975c377a0a4c42b16b3"
urllib.request.urlretrieve("https://anzhelian-edu.ru/datasets/stend/dom.py", "dom.py")
from dom import *

home, events, meter, h = загрузить(url)
print(f"Архив: {home.shape[0]} строк, Журнал: {events.shape[0]} событий, Счётчик: {meter.shape[0]} отметок\n")

# 2.1
print("2.1 Перерывы:")
gaps = home['time'].diff()
print(gaps[gaps > pd.Timedelta('1min')])

# 2.2
print("\n2.2 Пустые клетки:")
print(h.isna().sum()[h.isna().sum() > 0])

# === ГРАФИК 1 ===
print("\n--- ПОСТРОЕНИЕ ГРАФИКА 2.3 ---")
будни = h[h.index.dayofweek < 5]
будни["pir_kid"].groupby(будни.index.hour).mean().plot(kind="bar", title="График 2.3: Движение в детской по часам (будни)", color='skyblue')
plt.ylabel("Доля минут с движением")
plt.xlabel("Час суток")
plt.show()

# 2.4
print("\n2.4 Сдвиг:")
meter['круглое'] = meter['meter_time'].dt.floor('5min')
meter['сдвиг'] = (meter['meter_time'] - meter['круглое']).dt.total_seconds()
print("сдвиг:", meter['сдвиг'].value_counts().idxmax(), "сек")
print("изменения:", "нет" if meter[meter['сдвиг'].diff().abs() > 30].empty else "да")

# 2.6
print("\n2.6 CO2:")
h['ночь'] = (h.index.hour < 6) | (h.index.hour >= 23)
print(h.groupby('ночь')['co2_bed'].describe()[['mean', '50%', 'max']])

# 3.1
print("\n3.1 Баланс:")
розетки = ["p_fridge", "p_wh", "p_wash", "p_tv", "p_light"]
h["прочее"] = h["p_total"] - h[розетки].sum(axis=1)
print("прочее медиана:", h[h["p_wh"] > 0]["прочее"].resample("D").median().median(), "Вт")

# === ГРАФИК 2 ===
print("\n--- ПОСТРОЕНИЕ ГРАФИКА 3.2 ---")
(h["p_fridge"] > 50).resample("D").mean().plot(kind="bar", title="График 3.2: Доля работы холодильника по суткам", color='lightgreen')
plt.ylabel("Доля времени")
plt.xlabel("Дата")
plt.show()

# 3.5
print("\n3.5 Ночная вода:")
night_water = h.between_time("02:00", "05:00")["q_water"].resample("D").min()
print("ночная вода > 0:", "нет" if night_water[night_water > 0].empty else "да")

# === ГРАФИК 3 ===
print("\n--- ПОСТРОЕНИЕ ГРАФИКА 4.4 ---")
start_idx = h["t_kid"].isna().idxmax()
if pd.notna(start_idx):
    mask = (h.index >= start_idx - pd.Timedelta(hours=4)) & (h.index <= start_idx + pd.Timedelta(hours=4))
    h.loc[mask, "t_kid"].plot(title="График 4.4: Температура в детской (видны скачки и пропуски)", color='salmon', marker='.', linestyle='-')
    plt.ylabel("Температура (C)")
    plt.show()
else:
    print("Пропусков не найдено для графика")

# 4.6
print("\n4.6 Окно или радиатор:")
утро = h.between_time("11:00", "13:00")
разн = (утро["t_bed"] - утро["t_liv"]).resample("D").mean()
проветривали = h.between_time("06:00", "09:00")["win_bed"].resample("D").max()
df_check = pd.DataFrame({"разн": разн, "проветривали": проветривали}).dropna()
no_vent = df_check[df_check['проветривали'] == 0]
print("мин разн без проветривания:", round(no_vent['разн'].min(), 2), "C, дата:", no_vent['разн'].idxmin().strftime('%Y-%m-%d'))

# === ГРАФИК 4 ===
print("\n--- ПОСТРОЕНИЕ ГРАФИКА 4.6 ---")
df_check.plot(title="График 4.6: Разница температур спальня-гостиная и факт проветривания", secondary_y=['проветривали'])
plt.ylabel("Разница температур (C)")
plt.show()

# 4.7
print("\n4.7 Протечка:")
is_on = h["q_water"] > 0
groups = (is_on != is_on.shift()).cumsum()
lengths = is_on.groupby(groups).sum()
true_lengths = lengths[is_on.groupby(groups).first()]
if len(true_lengths) > 0 and true_lengths.max() > 360:
    max_len = true_lengths.max()
    max_group = true_lengths.idxmax()
    mask = groups == max_group
    print(f"протечка: {int(max_len)} мин, с {h[mask].index[0]} по {h[mask].index[-1]}")
else:
    print("протечек > 360 мин нет")

# === ГРАФИК 5 ===
print("\n--- ПОСТРОЕНИЕ ГРАФИКА 4.7 ---")
h["q_water"].loc["2026-01-26":].plot(title="График 4.7: Расход воды (видна длительная протечка 27 января)", color='blue')
plt.ylabel("Расход (л/мин)")
plt.show()

# 5.1
print("\n5.1 Подъёмы:")
morning_h = h.between_time("05:00", "10:00")
wake_up = morning_h[morning_h['h_bath'] > 70].groupby(pd.Grouper(freq='D')).apply(lambda x: x.index[0].strftime('%H:%M') if not x.empty else None)
print("подъёмы:", wake_up.dropna().tolist()[:7])

# 5.2
print("\n5.2 Стоимость:")
meter_daily = meter.set_index('meter_time')['kwh_total'].resample('D').last()
consumption = meter_daily.diff().dropna()
max_day = consumption.idxmax().strftime('%Y-%m-%d')
print(f"макс потребление: {max_day}, {consumption.max():.2f} кВт·ч, {consumption.max() * 6.5:.2f} руб.")

# 5.3
print("\n5.3 Доля:")
total = h['p_total'].sum()
print(f"бойлер: {h['p_wh'].sum()/total*100:.1f}%, холодильник: {h['p_fridge'].sum()/total*100:.1f}%")

# 5.4
print("\n5.4 Вода:")
water_daily = h['q_water'].resample('D').sum()
is_weekend = water_daily.index.dayofweek >= 5
water_by_type = water_daily.groupby(is_weekend).mean()
print(f"будни: {water_by_type.get(False, 0):.1f} л, выходные: {water_by_type.get(True, 0):.1f} л")

# 5.6
print("\n5.6 Корреляция:")
daily_means = h[['t_out', 't_supply']].resample('D').mean()
print("корреляция:", daily_means['t_out'].corr(daily_means['t_supply']).round(3))

# === ГРАФИК 6 ===
print("\n--- ПОСТРОЕНИЕ ГРАФИКА 5.6 ---")
daily_means.plot(kind='scatter', x='t_out', y='t_supply', title="График 5.6: Улица vs Батареи", color='orange')
plt.xlabel("Температура на улице (C)")
plt.ylabel("Температура воды в батареях (C)")
plt.show()

# 5.7
print("\n5.7 Ночной CO2:")
night_co2 = h.between_time("22:00", "08:00")
high_co2_hours = (night_co2['co2_bed'] > 1000).resample('D').sum() / 60
print("макс часов с co2>1000:", round(high_co2_hours.max(), 1))

print("\n=== ВСЕ ГРАФИКИ ПОСТРОЕНЫ. ПРОКРУТИТЕ ВЫВОД ВВЕРХ, ЧТОБЫ УВИДЕТЬ ИХ И СОХРАНИТЬ (ПКМ -> Сохранить изображение) ===")