SQL y Python para analizar precios de nuevos edificios en San Petersburgo o la habilidad más valiosa para un especialista en marketing en 2024

“¿Por qué necesito SQL y Python?” – Los especialistas en marketing o gerentes de productos hacen una pregunta razonable, especialmente en el campo de los bienes raíces, el comercio mayorista y los servicios empresariales: “No tenemos millones de filas de datos, ni registros, trabajamos exitosamente con varias tablas en Excel”.

Sí, de hecho, es posible que no tenga un almacén de datos corporativo en su empresa, y la base para automatizar el trabajo con datos es Power Query (que ahora es cada vez más difícil de hacer en la Federación de Rusia). Pero definitivamente tiene datos que recibe de departamentos relacionados, de CRM/CDP, MES y sistemas de control de procesos. Estos datos llegan regularmente en forma de archivos y usted los compara entre sí usando BUSCARV, los filtra con un embudo, los limpia usando Buscar o Reemplazar y hace resúmenes usando la función de tabla dinámica.

¿Cuáles son los serios problemas al trabajar con archivos Excel, además de las ventajas obvias?

  • Debe escribir en VBA para automatizar la rutina: por ejemplo, borrar datos o darles la forma deseada. O tendrá que solicitar estos scripts al departamento de TI, pero por alguna razón no tienen prisa por ayudarlo.

  • Es difícil trabajar con versiones y realizar copias de seguridad. Es posible que el código de macro deje de funcionar repentinamente y que tarde mucho tiempo en configurarse.

  • Para el trabajo completo necesita una licencia, hay un enlace a Windows, que ahora es extremadamente importante para muchas empresas en la Federación de Rusia con la transición a Linux. Y Python y DBMS (por ejemplo, SQLite o PostgreSQL) son de código abierto y se distribuyen gratuitamente.

  • Es posible que el código de macro ya no funcione después de actualizar Excel.

  • Excel tiene un límite de tamaño de un millón de filas y se congela cuando se trabaja en matrices grandes (más de 200.000 filas en máquinas de oficina promedio)

Todos estos problemas se resuelven con un simple DBMS. Ni siquiera necesitas configurar ningún servidor. Y todo el trabajo se basará en un lenguaje de consulta simple para este DBMS: SQL, que se puede dominar a un nivel serio en 2-3 meses de capacitación. Python será una herramienta auxiliar para nosotros en el procesamiento de datos.

En este primer artículo mío sobre Habré, haré un mínimo de comparaciones directas entre SQL y Excel y simplemente mostraré cómo puede funcionar. ¡Llegar al punto!

Tarea

Al tener datos del proveedor sobre la venta de apartamentos en edificios nuevos en formato csv, el comercializador, basándose en ellos, debe responder preguntas sobre en qué zona de San Petersburgo es mejor construir un nuevo complejo residencial. ¿Dónde se produjo el mayor aumento de precios y qué influye? ¿Cómo han subido o bajado los bienes raíces en relación con otros activos?

Archivo fuente en formato csv

Archivo fuente en formato csv

Además, cada mes llegarán nuevos datos de transacciones y será necesario actualizar nuestro informe. ¿Qué haremos para solucionar el problema ahora y acelerar el trabajo en el futuro?

  • Carguemos los archivos en Python, carguemos los módulos necesarios para el trabajo.

  • Limpiemos los datos de la basura (comas, tipo de datos incorrecto, fechas incorrectas)

  • Calculemos la distancia al centro de San Petersburgo a cada casa en 30 segundos.

  • En 1 minuto crearemos un DBMS y nos conectaremos a él.

  • Creemos campos de cálculo en SQL.

  • Combinemos 5 mesas en una.

  • Hagamos un gráfico y una tabla dinámica.

¿Dónde trabajaremos? La forma más sencilla es empezar a trabajar en Código VShabiendo instalado previamente anaconda. Cuando inicie VSCode, seleccione “Nuevo archivo” y luego “Jupiter Notebook”.

Seleccionar el entorno anaconda3 para trabajar después de crear el archivo ipynb en VSCode

Seleccionar el entorno anaconda3 para trabajar después de crear el archivo ipynb en VSCode

Primero, necesitamos importar módulos, también llamados bibliotecas. Se trata de “trozos” de código terminado ya creados por otros programadores. Módulo Geopy requiere instalación a través de la línea de comando pip install geopyno está disponible en la tienda de código abierto conda/anaconda, por lo que lo instalamos a través de pip.

import pandas as pd   #работа с данными
import sqlite3    #СУБД для создания локальной БД. Скоро это будет duckBD:)
from geopy.distance import geodesic   #вычисление расстояний по координатам
import matplotlib as plt    #графики
import seaborn as sns    #графики

Subir archivos para trabajar

Trabajar en Jupyter Notebook parece ingresar un comando en una celda en Python y obtener el resultado en la salida o en output

Importación de la biblioteca Pandas para trabajar con datos, ejemplos e importación de tablas y aritmética

Importación de la biblioteca Pandas para trabajar con datos, ejemplos e importación de tablas y aritmética

Puedes subir archivos a un documento con el comando read_csv, indicando la dirección donde se almacena este archivo. También puede proporcionar un enlace en Internet o almacenamiento en red. Pandas puede leer otros tipos de archivos como sql, json, spss, sas dump.

df = pd.read_csv("/Users/andrew/Documents/DataSets/Dataflat_Oct_2023_LO/realty_sold_07112023_LO.csv", sep = ';')
df   #выводим результат
Más de 60 columnas en una tabla u objeto DataFrame

Más de 60 columnas en una tabla u objeto DataFrame

Para mayor claridad, en el futuro la tabla será más grande y no mostraremos todas las columnas. Mientras puedas ver el objeto. DataFrame bibliotecas pandas. Se trata de una matriz multidimensional o, más simplemente, una tabla familiar con filas o columnas.

10 filas aleatorias de la tabla llamada por el método de muestra

10 filas aleatorias de la tabla llamada por el método de muestra

Ingresemos un comando para obtener el número de líneas en DataFrame

231.008 filas en la tabla de transacciones de apartamentos

231.008 filas en la tabla de transacciones de apartamentos

Cuando hay muchas columnas en la tabla, solo verá 20 columnas. En las opciones de Pandas puedes cambiar las opciones de visualización para poder desplazarte hacia la izquierda y mostrar todas las columnas.

pd.options.display.float_format="{:.2f}".format

# Максимальное число отображаемых колонок.
pd.set_option('display.max_columns', 500)  
# Максимальное число отображаемых строк.
pd.set_option('display.max_rows', 500)   

Transformación y limpieza de datos.

Cargamos los datos desde un archivo csv, lo cual es bastante común. formato en un entorno corporativo, y probablemente no le agradará que, a diferencia de Excel, Pandas no intente adivinar el tipo de datos al cargar un archivo (cadena, número, fecha). Los tipos de datos deben especificarse explícitamente, pero vale la pena, lo haremos una vez y el código realizará las manipulaciones necesarias repetidamente, liberando un tiempo valioso.

Comprobemos qué tipos de datos se asignaron a las columnas durante la carga.

Debido al ancho del Dataframe, la captura de pantalla se divide en 2 partes

Debido al ancho del Dataframe, la captura de pantalla se divide en 2 partes

En primer lugar, nos interesan las fechas, todas se leen como object. Para convertir tipos, utilizamos el método. hasta_fechahora.

df('Дата ДДУ') = pd.to_datetime(df('Дата ДДУ'), format="%d/%m/%y")
df('Дата регистрации') = pd.to_datetime(df('Дата регистрации'), format="%d/%m/%y")
df('Дата регистрации модель') = pd.to_datetime(df('Дата регистрации модель'), format="%d/%m/%y")
df('Дата обременения') = pd.to_datetime(df('Дата обременения'), format="%d/%m/%y")
Establecer el formato de fecha al importar un archivo

Además de los métodos descritos anteriormente, existe otro: establecer la fecha inmediatamente después de la importación. Necesitas especificar un parámetro parse_dates

pd.read_csv('file_name.csv', parse_dates=('Deal_date'))

A continuación vemos que el programa también leyó algunos números como cadenas o object. Todo esto sucedió porque la parte entera de la parte fraccionaria está separada por una coma, no por un punto. Escribamos un código corto que cambie la coma a un punto y convierta la cadena a un tipo numérico.

df('Площадь') = df('Площадь').str.replace(',', '.').astype(float)
df('lat') = df('lat').str.replace(',', '.').astype(float)
df('lng') = df('lng').str.replace(',', '.').astype(float)
df('Цена кв. м') = df('Цена кв. м').str.replace(',', '.').astype(float)

No es necesario utilizar el principio DRY (No repita su código) en el análisis de datos. Si lo desea, puede utilizar construcciones, bucles y funciones del lenguaje Python, pero este artículo utiliza ejemplos simples y comprensibles de métodos integrados.

Estamos procesando la “Fecha de Vencimiento”. En la tabla original estaba “T2 2017”, extraemos el número con 4 caracteres: el año usando una expresión regular.

El tercer trimestre de 2019 debe ser reemplazado antes del 01/01/2019

3T 2019 necesita ser reemplazado con 01.01.2019

df('Год сдачи') = df('Срок сдачи').str.extract(r'(\d{4})')  #Выделяем год из строки
df('Год сдачи') = pd.to_datetime(df('Год сдачи'))  #присваевам тип даты

Estamos procesando la fecha de inicio de ventas. La tabla original tenía el tipo flotante “2020.2”. Divide al grano tomando la primera parte del número. Habiendo convertido primero el número flotante en una cadena.

df('Старт продаж К') = df('Старт продаж К').astype(str)
df('Старт продаж К') = df('Старт продаж К').astype(str).str.split('.').str(0)

En el conjunto de datos, el precio total de la transacción estaba vacío, por lo que decidimos calcularlo a partir del área y el precio por metro cuadrado.

#создаем расчетный столбец и добавляем его в датасет
df('Цена производная') = df('Цена кв. м') * df('Площадь') 

En el conjunto de datos con el que necesitamos trabajar, los nombres de las columnas están en ruso, lo que no será tan conveniente al escribir consultas SQL. Esto no es necesario, pero cambiaremos el nombre de las columnas en latín.

código oculto
new_column_names = {
    'ID ЖК': 'id_zhk',
    'ЖК рус': 'zhk_rus',
    'ЖК англ': 'zhk_angl',
    'Район Город': 'rayon_gorod',
    'Округ Направление': 'okrug_napravleniye',
    'Регион': 'region',
    'АТД': 'atd',
    'Застройщик ЖК': 'zastroishchik_zhk',
    'Площадь': 'ploshchad',
    'Комнатность': 'komnatnost',
    'Тип Комнатности': 'tip_komnatnosti',
    'Этаж': 'etazh',
    'Номер': 'nomer',
    'Тип помещения': 'tip_pomeshcheniya',
    'Корпус': 'korpus',
    'Дата регистрации': 'data_registratsii',
    'Условия обременения': 'usloviya_obremeneniya',
    'Номер обременения': 'nomer_obremeneniya',
    'Дата обременения': 'data_obremeneniya',
    'Залогодержатель': 'zalogkhozhatel',
    'Длительность обременения': 'dlitel_obremeneniya',
    'Тип обременения': 'tip_obremeneniya',
    'Оценка цены': 'otsenka_tseny',
    'Дата ДДУ': 'data_ddu',
    'Уступка': 'ustupka',
    'Купил лотов в ЖК': 'kupil_lotov_v_zhk',
    'ID Корпус': 'id_korpus',
    'класс': 'klass',
    'Срок сдачи': 'srok_sdachi',
    'Стадия строительства': 'stadiya_stroitelstva',
    'lat': 'lat',
    'lng': 'lng',
    'Ипотека': 'ipoteka',
    'Секция': 'sektsiya',
    'Отделка': 'otdelka',
    'Старт продаж К': 'start_prodazh_k',
    'Продавец ЮЛ': 'prodavets_yul',
    'Зона': 'zona',
    'Купил кв и ап в ЖК': 'kupil_kv_i_ap_v_zhk',
    'Стадия строительства в дату ДДУ': 'stadiya_stroitelstva_v_data_ddu',
    'Цена ДДУ': 'tsena_ddu',
    'Цена со скидкой': 'tsena_so_skidkoy',
    'Тип сделки': 'tip_sdelki',
    'Разница дат': 'raznitsa_dat',
    'Дата регистрации модель': 'data_registratsii_model',
    'version': 'version',
    'Участок': 'uchastok',
    'ФИО': 'fio',
    'Цена кв. м': 'price_m2',
    'ID дом.рф': 'id_dom_rf',
    'Оценка по ЕИСЖС': 'otsenka_po_eiszhzs',
    'Unnamed: 51': 'unnamed_51',
    'Год сдачи': 'god_sdachi',
    'Цена производная': 'price'
}

df = df.rename(columns=new_column_names)

Calculemos la distancia hasta el Hermitage.

Esto es necesario para entender cómo cambia el precio según el centro de gravedad de una ciudad turística. Nuestro archivo tiene 2 columnas con la latitud y longitud de la propiedad. Es correcto aplicar este indicador solo a los datos de la tabla LCD, y no a las transacciones en ellas (para no ocupar memoria permanente), pero por simplicidad lo haremos en ambos sentidos.

# координаты Эрмитажа
a = (59.939442, 30.314131)  
#применение лямбда функции, которая считает расстояние по координатам
df.apply(lambda row: geodesic(a, (row('lat'), row('lng'))).km, axis=1)
La columna calculada de la derecha muestra la distancia al Hermitage.

La columna calculada de la derecha muestra la distancia al Hermitage.

Importación de datos históricos sobre el tipo de cambio del dólar, el oro, la Bolsa de Moscú y el petróleo.

Repetí las mismas operaciones con otros archivos de datos financieros. Para ahorrar espacio en el artículo y tu tiempo, solo mostraré una captura de pantalla de la descarga, ya que el código completo es similar a completar los datos de una transacción. Hubo la misma limpieza de datos y reducción a los tipos requeridos.

Cursos básicos del 2013 al 2014.

Cursos básicos del 2013 al 2014.

Entonces, hemos cargado 6 tablas, recuerde las variables, a continuación serán necesarias para nombrar las tablas en la base de datos:

  1. Tabla de ofertas en variable df

  2. Tabla de conjuntos residenciales donde se vendieron estos apartamentos. Variable zk

  3. Tablas con datos financieros de 4 fuentes en variables relevantes, p.e. gold

Crea una base de datos en tres líneas.

Aquí terminó casi todo Python, era necesario para obtener datos de csv, borrarlos, cambiarles el nombre y agregar la distancia al Hermitage allí. Puede enriquecer sus datos con bibliotecas pagas como dadataaplique sus modelos de aprendizaje automático para clasificar clientes o predecir la pérdida de clientes.

Nuestro objetivo ahora es comenzar a escribir consultas de datos en SQL, que, a diferencia de Python, es más fácil de dominar para los especialistas digitales y los gerentes financieros o comerciales.

En este ejemplo, crearemos una base de datos sin servidor muy conveniente. SQlite. Sin embargo, puedes escribir en el mismo archivo una conexión a cualquier otra base de datos que tenga tu empresa.

con = sqlite3.connect('spb_estate')
cur = con.cursor()

to_sql envía un marco de datos a las tablas de la base de datos:

zk.to_sql('zk',con,index=False,if_exists="replace")   #таблица ЖК
df.to_sql('df',con,index=False,if_exists="replace")   #таблица сделок
ind.to_sql('ind',con,index=False,if_exists="replace")  #индексы мосбиржи с 2013
q.to_sql('q',con,index=False,if_exists="replace")   #курсы доллара с 2013
oil.to_sql('oil',con,index=False,if_exists="replace")   #курсы на brent 
metals.to_sql('metals', con, index=False, if_exists="replace")   #курсы на золото

Cuaderno Jupyter o DBeaver para trabajo SQL

Dónde y cómo trabajar con la base de datos es una cuestión de conveniencia y costumbre. Arriba, en el directorio (carpeta del proyecto donde se encuentra el script Python), creamos un archivo de base de datos SQLite. Podemos acceder a las tablas desde el programa cliente DBeaver.

  • Descargar DBeaver

  • Haga clic en el botón de conexión y seleccione SQLite

  • Para trabajar necesitarás controladores, el “castor” los descargará automáticamente

  • Haga clic en “script SQL” y ejecute con

A la izquierda tendremos nuestras tablas que creamos arriba. A la derecha está la interfaz para escribir y ejecutar comandos SQL.

Interfaz para consultas de bases de datos DBeaver

Interfaz para consultas de bases de datos DBeaver

SQL en Python

Si no desea resaltado de sintaxis listo para usar, diagramas de relaciones de tablas, sugerencias, pero desea un análisis intenso, puede continuar analizando datos en el entorno interactivo de Python usando SQL. Ya hemos creado la base de datos, solo queda enviarle comandos.

Para comodidad del analista, se crea una función. Como entrada, acepta una solicitud en forma de cadena y nos devuelve el resultado de la consulta de la base de datos.

def select(sql):
  return pd.read_sql(sql,con)

No hay magia en esto, tal como escribí arriba. Pandas También puede leer archivos SQL. variable sql La cadena de consulta en lenguaje SQL está “protegida” y la dirección de conexión se asigna a la variable conn. (véase más arriba con = sqlite3.connect('spb_estate') )

#Пандас, прочитай sql фаил, по запросу, по подключению в переменной con
pd.read_sql('SELECT avg(price) FROM df', con) 

pd.read_sql('Запрос к базе данных в строке', Подключение, которое мы делали ранее)

Veamos cómo se llenan las tablas de la base de datos. Hacemos una consulta a la base de datos, obtenemos una lista de tablas que se encuentran en nuestra base de datos. Esto es lo que parece:

sql=""'select name from sqlite_master where type="table";'''  #запрос
select(sql)   #вывод результата
Una consulta de base de datos que muestra tablas existentes.

Una consulta de base de datos que muestra tablas existentes.

Y aquí están nuestras 6 mesas. Puede trabajar de forma segura en el análisis de datos utilizando SQL

Ejemplo de análisis de datos utilizando lenguaje SQL.

Todos los ejemplos de consultas SQL se darán con resaltado de sintaxis.

hagamos el primero select , lo que nos ayudará a comprender los límites temporales de los datos. Consigamos los valores mínimo y máximo.

select --достань мне следующие данные:
    max(data_registratsii), -- максимальная дата
    min(data_registratsii), -- минимальная дата
    min(price), max(price), 
    min(price_m2), 
    max(price_m2), 
    min(ploshchad), 
    max(ploshchad)
from df   -- из какой таблицы?
where data_registratsii not null -- где дата не пустая
and price not null -- и цена не пустая
and -- и
tip_pomeshcheniya="квартира" 
and price != 0.00 -- цена на кватиры не 0
Recibimos un área mínima de 15 metros, esto parece ridículo y parece desechable, ¡pero la gente compra esos apartamentos!  Definitivamente se trata de un apartamento, no de un trastero, ya que los filtramos en la solicitud.

Recibimos un área mínima de 15 metros, esto parece ridículo y parece desechable, ¡pero la gente compra esos apartamentos! Definitivamente se trata de un apartamento, no de un trastero, ya que los filtramos en la solicitud.

Creemos una tabla dinámica, agrupemos todas las transacciones por año desde 2014 hasta 2023 en una consulta y mostremos los indicadores necesarios en las columnas.

Select --достань мне следующие данные:
    -- приводим дату к началу года
    date(data_registratsii, 'start of year') as date_year
    , count(*) -- считаем количество строк
    , avg(price)
    , avg(price_m2) -- считаем среднее по площади сделки
    , avg(ipoteka) 
    , avg(ploshchad)
    , min(ploshchad)
    , avg(dlitel_obremeneniya)


from df -- указываем откуда брать данные
where data_registratsii not null 
and price not null 
and tip_pomeshcheniya="квартира" 
and price != 0.00 -- фильруем запрос

 -- группируем по дате все данные
group by date(data_registratsii, 'start of year') 
Transacciones agrupadas por año

Transacciones agrupadas por año

Vimos que hubo muy pocas transacciones antes de 2016 y no vale la pena analizarlas. Analizamos únicamente datos sobre transacciones en el mercado primario de 2016 a 2023.

Tenemos muchos datos, más 200.000 líneas de transacción, y necesitamos entender cómo se distribuyen los precios dentro de este conjunto. Dividámoslos en percentiles y observemos los precios promedio dentro de estos grupos. Creemos “cestas” usando la función de ventana. ntileque devolverá un valor del 1 al 10 para cada fila del conjunto de datos.

with cte as (

-- В начале нашли процентиль для каждой сделки и другие параметры
SELECT 
  price, 
  price_m2, 
  ploshchad, 
  data_registratsii, 
  NTILE(10) OVER (ORDER BY ploshchad) as percentile
FROM df
where data_registratsii not null 
  and price not null and tip_pomeshcheniya="квартира"
)

-- Потом на основе первой таблицы, сделали группировку по percentile
select 
  percentile, 
  min(ploshchad), 
  max(ploshchad), 
  avg(price), 
  avg(price_m2), 
  count(*) from cte
group by 1 -- группировка по первому столбцу в select

SQLite usando la función de clasificación de ventanas ntile dividió todo el conjunto de datos en 10 partes iguales por área. Esto puede utilizarse para segmentar el mercado comparando sus precios con los de sus competidores.

Tenga en cuenta que el número de operaciones en cada intervalo es el mismo.

Tenga en cuenta que el número de operaciones en cada intervalo es el mismo.

Conectar tablas usando join

Ahora agreguemos datos financieros. ¿Cuál era el tipo de cambio del dólar en la fecha de registro de la transacción? Agregaremos otras tablas usando la clave de fecha en la tabla principal de transacciones. Excel tiene un análogo a esto: la función BUSCARV.

select 
    id_zhk,
    data_registratsii,
    zhk_rus,
    price,  
    ipoteka,
    ploshchad, 
    price_m2 as rub_m2_price,
    price_m2 / Quote as m2_dollar_price,
    price_m2 / Quote / oil.close  as m2_oil_price,
    price_m2 / Quote / gold as m2_gold_price,
    price_m2 / OPEN as mosex_m2_pice

from df
-- добавим данные по доллару на дату
join q on q.date = df.data_registratsii

-- добавим данные по нефти на дату
join oil on oil.date = df.data_registratsii 

-- добавим данные по цене золота
join metals on metals.date = df.data_registratsii 

-- добавим данные по цене индексов
join ind on ind.TRADEDATE = df.data_registratsii

where data_registratsii not null 
and price not null 
and tip_pomeshcheniya="квартира" 
and price != 0.00 
and data_registratsii > '2015.01.01' 
and name="Индекс МосБиржи"
order by date(data_registratsii)
Resultado de agregar datos financieros a la tabla de transacciones

Resultado de agregar datos financieros a la tabla de transacciones

Averigüemos qué porcentaje de apartamentos se vendieron con hipoteca en un año determinado y sigamos la tendencia del mercado.

select 
    date(data_registratsii, 'start of month') as date_m,
    avg(ipoteka) as ipoteka
from df

join q on q.date = df.data_registratsii
join oil on oil.date = df.data_registratsii
join metals on metals.date = df.data_registratsii
where data_registratsii not null 
and price not null 
and tip_pomeshcheniya="квартира" 
and price != 0.00 
and data_registratsii > '2015.01.01'

group by 1
order by 1 asc

A partir de la tabla resultante haremos un gráfico en Python usando la biblioteca. seaborn y matplotlib

plt.figure(figsize=(20, 6))   #размер графика
sns.lineplot(x='date_m', y='ipoteka', data=select(sql))    #оси и dataframe
sns.set_style("darkgrid")    #стиль
plt.title('Доля сделок в ипотеку')   #заголовок
plt.xticks(rotation=90)   #наклон дат
plt.show()   #показать график
Cuota de operaciones hipotecarias de 2016 a 2023

Cuota de operaciones hipotecarias de 2016 a 2023

La duración media del plazo del gravamen (hipoteca) se ha duplicado

La duración media del plazo del gravamen (hipoteca) se ha duplicado

Precio por metro en dólares americanos

Precio por metro en dólares americanos

Ahora agrupemos nuestros datos por distancia desde el Hermitage en kilómetros. También queremos ver la dinámica en las columnas en años, para ello necesitaremos crear columnas condicionales usando una construcción lógica. caso cuando, que literalmente dice “Si la fecha de registro es entre 2017 y 2018, entonces crea una columna con los valores de este año”. Este es uno de mis diseños favoritos y más comunes.

select 
    round(distance_hermitage, -2),
    count(case when data_registratsii between '2016-01-01' and '2017-01-01' then data_registratsii end) as s2016,
    count(case when data_registratsii between '2017-01-01' and '2018-01-01' then data_registratsii end) as s2017,
    count(case when data_registratsii between '2018-01-01' and '2019-01-01' then data_registratsii end) as s2018,
    count(case when data_registratsii between '2019-01-01' and '2020-01-01' then data_registratsii end) as s2019,
    count(case when data_registratsii between '2020-01-01' and '2021-01-01' then data_registratsii end) as s2020,
    count(case when data_registratsii between '2021-01-01' and '2022-01-01' then data_registratsii end) as s2021,
    count(case when data_registratsii between '2022-01-01' and '2023-01-01' then data_registratsii end) as s2022,
    count(case when data_registratsii between '2023-01-01' and '2024-01-01' then data_registratsii end) as s2023
from df

join q on q.date = df.data_registratsii
join oil on oil.date = df.data_registratsii
join metals on metals.date = df.data_registratsii
where data_registratsii not null and price not null and tip_pomeshcheniya="квартира" and price != 0.00 and data_registratsii > '2015.01.01'

group by 1
order by 1 asc
limit 20

Hagamos un mapa de calor para la tabla resultante. dataframe(como el formato condicional en Excel), aplique formato condicional de celdas en dataframe. Quizás para el desarrollador estas tablas ayuden a determinar el precio efectivo y la distancia de la ubicación del desarrollo al centro histórico de San Petersburgo.

select(sql).style.background_gradient(axis=None, vmin=1, vmax=10000)  
Matriz de distancia y tiempo de los nuevos edificios de San Petersburgo

Matriz de distancia y tiempo de los nuevos edificios de San Petersburgo

¿Qué complejo residencial tiene más transacciones desde el 1 de enero de 2020? Puede leer fácilmente la solicitud usted mismo.

select 
    df.zhk_rus,
    okrug_napravleniye,
    rayon_gorod,
    count(data_registratsii) as cnt_deal,
    avg(price_m2) as rub_m2_price,
    avg(price_m2) / Quote as m2_dollar_price,
    avg(ipoteka) as ipoteka_precent,
    max(date(god_sdachi)) as max_god_sdachi,
    min(distance_hermitage)
    
from df

join q on q.date = df.data_registratsii
where data_registratsii not null and price not null 
and tip_pomeshcheniya="квартира" and price != 0.00 
and data_registratsii > '2020.01.01'

group by 1,2 -- групируем по 1 и 2 столбцу в select
order by 4 desc -- сортируем по убывани по 4 стобцу в select
Suman 2.896 transacciones en el conjunto residencial New Horizons

Suman 2.896 transacciones en el conjunto residencial New Horizons

¿Cuáles son los tres principales líderes en préstamos hipotecarios desde 2016 por número de transacciones?

select 
    zalogkhozhatel,
    count(data_registratsii) as cnt_deal,
    sum(price),
    avg(dlitel_obremeneniya),
    avg(price_m2) as rub_m2_price
    
from df

join q on q.date = df.data_registratsii
join oil on oil.date = df.data_registratsii
join metals on metals.date = df.data_registratsii
where data_registratsii not null and price not null and tip_pomeshcheniya="квартира" and price != 0.00 and data_registratsii > '2016.01.01'

group by 1
order by 2 desc
limit 10
plt.figure(figsize=(20, 8))
sns.barplot(x='zalogkhozhatel', y='cnt_deal', data=select(sql))
sns.set_style("darkgrid")
plt.title('Количество сделок с обременением на первичном рынке с 2016 года по третий квартал 2023 года в Спб')
plt.xticks(rotation=90)
plt.show()
Los tres primeros Sberbank, VTB, Bank St. Petersburgo

Los tres primeros Sberbank, VTB, Bank St. Petersburgo

En lugar de una conclusión

Si su empresa tiene un proceso estándar para trabajar con datos, por ejemplo, analizar los precios, el inventario y las ventas de la competencia, entonces puede organizar fácilmente dicho proceso de procesamiento y visualización de datos utilizando código usted mismo o con la ayuda de un analista.

No tienes que jugar con tablas de Excel y rehacer las mismas manipulaciones cada vez, ¡simplemente puedes pasar los datos a través de un script similar que prepara los informes que necesitas!

PD

El conjunto de datos utilizado es comercial y no está disponible públicamente, por lo que no se puede publicar.

Publicaciones Similares

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *