Интерактивный дашборд динамики цен на недвижимость на основе Parquet и DuckDB
Материал из Поле цифровой дидактики
Описание проекта
Этот проект демонстрирует создание интерактивного дашборда для анализа динамики цен на недвижимость с использованием DuckDB (встраиваемой аналитической базы данных) и Plotly Dash. Проект наглядно показывает ключевые методы работы с большими данными:
- Пакетная обработка: Эффективная работа с большими объёмами данных без полной загрузки в память.
- Колоночное хранение: Использование формата Parquet для ускорения аналитических запросов и экономии места.
- Векторизованные SQL-запросы: Агрегация и фильтрация данных на лету с помощью DuckDB.
В качестве источника данных используется открытый набор «Индексы цен на рынке жилья» от Росстата (ЕМИСС), доступный в формате Parquet.
Источник данных
Датасет «Индексы цен на рынке жилья (ЕМИСС)» от Росстата.
- Страница датасета: https://repository.econdata.tech/dataset/emiss_30925
- Прямая ссылка на Parquet: https://repository.econdata.tech/dataset/emiss_30925/resource/60378ec6-c7a8-4cec-9a59-e841ca206b3f
Код дашборда
Код для создания интерактивного дашборда. Он выполняет следующие шаги:
- Подключается к DuckDB и загружает данные из Parquet-файла.
- Создаёт интерактивный веб-интерфейс с выпадающим списком для выбора региона.
- Строит линейный график динамики цен для выбранного региона.
- Отображает среднюю цену за весь период.
import duckdb
import dash
from dash import dcc, html, Input, Output
import plotly.express as px
import pandas as pd
# 1. Подключение к DuckDB и загрузка данных
conn = duckdb.connect()
# Прямая ссылка на Parquet-файл (можно заменить на локальный путь)
DATA_URL = "https://repository.econdata.tech/dataset/emiss_30925/resource/60378ec6-c7a8-4cec-9a59-e841ca206b3f"
# Регистрируем Parquet-файл как таблицу в DuckDB
conn.execute(f"""
CREATE OR REPLACE TABLE real_estate AS
SELECT * FROM '{DATA_URL}'
""")
# Предварительно получаем список уникальных регионов для выпадающего списка
regions_df = conn.execute("SELECT DISTINCT region FROM real_estate ORDER BY region").fetchdf()
regions = regions_df['region'].tolist()
# 2. Инициализация Dash-приложения
app = dash.Dash(__name__)
app.layout = html.Div([
html.H1("📈 Интерактивный дашборд: Динамика цен на недвижимость",
style={'textAlign': 'center'}),
html.Label("Выберите регион:"),
dcc.Dropdown(
id='region-dropdown',
options=[{'label': r, 'value': r} for r in regions],
value=regions[0], # значение по умолчанию
clearable=False
),
dcc.Graph(id='price-chart'),
html.Div(id='avg-price-text', style={'marginTop': 20, 'fontSize': 20})
])
# 3. Callback для обновления графика и текста при смене региона
@app.callback(
[Output('price-chart', 'figure'),
Output('avg-price-text', 'children')],
Input('region-dropdown', 'value')
)
def update_dashboard(selected_region):
# SQL-запрос с агрегацией данных по выбранному региону
query = f"""
SELECT
date,
AVG(price_index) as avg_index
FROM real_estate
WHERE region = '{selected_region}'
GROUP BY date
ORDER BY date
"""
df = conn.execute(query).fetchdf()
# Создание графика Plotly
fig = px.line(df, x='date', y='avg_index',
title=f'Динамика индекса цен в регионе: {selected_region}',
labels={'avg_index': 'Индекс цен', 'date': 'Дата'})
# Расчёт среднего значения для текстового блока
avg_price = df['avg_index'].mean()
avg_text = f"Средний индекс цен за период: {avg_price:.2f}"
return fig, avg_text
# 4. Запуск сервера
if __name__ == '__main__':
app.run_server(debug=True)
Как это работает
- DuckDB напрямую читает Parquet-файл, извлекая только нужные колонки и строки (благодаря предикативному пушдауну, Predicate Pushdown). Это позволяет обрабатывать гигабайты данных на обычном компьютере.
- Dash создаёт веб-интерфейс на чистом Python, без необходимости писать HTML или JavaScript.
- При выборе региона в выпадающем списке выполняется SQL-запрос к DuckDB, который агрегирует данные и возвращает результат для построения графика.
Демонстрация ключевых методов Big Data
- Экономия памяти: DuckDB загружает данные частями (chunks), не расходуя всю оперативную память.
- Колоночное хранение (Parquet): Чтение только нужных колонок ускоряет запросы в десятки раз по сравнению с CSV.
- Векторизованные запросы: DuckDB использует SIMD-инструкции процессора для параллельной обработки данных.
Ссылки
- Документация DuckDB
- [Документация Plotly Dash](https://dash.plotly.com/)
- [Датасет ЕМИСС](https://repository.econdata.tech/dataset/emiss_30925)
