poseg's picture
add app.py
1ad1b1c
import json
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
import streamlit as st
import numpy as np
from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta
from pathlib import Path
from PIL import Image
import app_scripts.s_02_map as smap
import app_scripts.s_01_get_data as get_data
def drop_day(date: datetime) -> datetime:
return datetime(year=date.year, month=date.month, day=1)
# penciltip_im = Image.open(r'C:\Users\EPostolit\Programs\HHru\site (streamlit)\final\data\pictures\penciltip.png')
penciltip_im = Image.open(Path() / 'data' / 'pictures' / 'penciltip.png')
st.set_page_config(
page_title='Безработица, hh-ru',
page_icon= penciltip_im,
layout='wide'
)
def pm_num(num):
if num > 0:
return '+' + "%.1f" % num
else:
return "%.1f" % num
VTB_COLORS = [(0.228845, 0.413827, 0.561235),
(0.301203, 0.652293, 0.707487),
(0.834794, 0.267854, 0.225356),
(0.967809, 0.848523, 0.288235),
(0.0480806, 0.0308608, 0.0346505),
(0.744229, 0.744089, 0.740097),
(0.99389, 0.970688, 0.797143),
(0.721352, 0.321019, 0.293811)
]
# print(dir(scr))
# DATA_FOLDER = Path(r'data')
# MAP_DATA = DATA_FOLDER / 'map_data'
st.title('Альтернативные данные по безработице.\nНа основе открытых данных из Headhunter')
st.write('[Безработица в мае по данным Росстата обновляет исторический минимум 2-ой месяц подряд](https://t.me/xtxixty/1951), достигнув отметки в 3.9%.\
Все это происходит на фоне массового ухода иностранных компаний с российского рынка и [падения производства](https://t.me/xtxixty/1951).\
О том, что разброс оценки безработицы из-за не очень большой выборки в ~77 тыс. человек | ~0.1% рабочей силы может быть большим писали [ранее](https://t.me/xtxixty/1792). ')
# st.markdown('# Headhunter в России')
counties = smap.get_counties()
stats_df = smap.prepare_stats_df()
# stats_df.to_excel('delte0.xlsx', index=False)
# stats_df[stats_df.columns[0:4]]
min_date = min(stats_df['date'])
max_date = max(stats_df['date'])
# min_date
# max_date
# prof_name = st.sidebar.selectbox('Проф. область',
# np.unique([str(i) for i in stats_df.prof_name]))
prof_name = 'все'
date = st.slider('Дата', min_value=min_date.to_pydatetime(), max_value=max_date.to_pydatetime(),
value=max_date.to_pydatetime(), step=timedelta(days=30))
date = drop_day(date)
prof_df = stats_df[stats_df['prof_name'] == prof_name]
show_df = prof_df[(stats_df['date'] == date)]
# show_df.shape
show_df.to_excel('delte1.xlsx', index=False)
fig = go.Figure(go.Choroplethmapbox(geojson=counties,
locations=show_df['map_region_id'],
z=show_df['hh_index'],
text=show_df['name'],
# colorscale=[[0, f'rgb{VTB_COLORS[1]}'],
# [qq[1], f'rgb{VTB_COLORS[3]}'],
# [qq[2], f'rgb{VTB_COLORS[2]}'],
# [1, f'rgb{VTB_COLORS[2]}']],
colorscale=[[0, f'rgb{VTB_COLORS[1]}'],
[0.4, f'rgb{VTB_COLORS[3]}'],
[0.8, f'rgb{VTB_COLORS[2]}'],
[1.0, f'rgb{VTB_COLORS[2]}']],
colorbar_thickness=20,
customdata=np.stack([show_df['hh_index'], show_df['vacancies'].apply(pm_num), show_df['resumes'].apply(pm_num), show_df['hh_index_change'].apply(pm_num)], axis=-1),
hovertemplate='<b>%{text}</b>'+ '<br>' +
'hh индекс: %{z}' + '<br>' +
'изменение индекса: %{customdata[3]}% м/м' + '<br>' +
'активных вакансий: %{customdata[1]}% м/м' + '<br>' +
'активных резюме: %{customdata[2]}% м/м'# + '<br>' #+
# 'Всего случаев: %{customdata[2]}' + '<br>' +
# 'Выздоровело: %{customdata[3]}' +
'<extra></extra>',
hoverinfo='text, z'))
fig.update_layout(mapbox_style="carto-positron",
mapbox_zoom=1, mapbox_center = {"lat": 66, "lon": 94})
fig.update_traces(marker_line_width=0)
fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0})
st.plotly_chart(fig, use_container_width=True)
st.write('''На карте изображено распределение [hh-index-a](https://ru.wikipedia.org/wiki/HeadHunter#hh.%D0%B8%D0%BD%D0%B4%D0%B5%D0%BA%D1%81) в РФ, равного отношению числа активных резюме к количеству открытых вакансий на сервисах [hh.ru](http://hh.ru), т.е. прокси для безработицы.''')
# st.dataframe(stats_df[stats_df['location'] == 'total'])
# st.sidebar.write('hello')
# st.write('this is dataframe with data')
# st.dataframe(show_df)
# quantile graph by region
# TODO implement the ability to choose region
ros_df = get_data.load_rs_unemploment()
quantiles = (0.05, 0.5, 0.95)
quantile_data = prof_df[['date', 'hh_index', 'name']].groupby('date').apply(lambda df:
np.quantile(df['hh_index'], quantiles))
lower = pd.Series(index=quantile_data.index, data=[val[0] for val in quantile_data.values])
median = pd.Series(index=quantile_data.index, data=[val[1] for val in quantile_data.values])
upper = pd.Series(index=quantile_data.index, data=[val[2] for val in quantile_data.values])
hh_index_df = stats_df[stats_df['location'] == 'total']
hh_index_df.to_excel('delte.xlsx', index=False)
blue_color_str = f'rgb{VTB_COLORS[0]}'
lightblue_color_str = f'rgb{VTB_COLORS[1]}'
rosstat_color_str = f'rgb{VTB_COLORS[2]}'
layout = go.Layout(
paper_bgcolor=f'rgb{VTB_COLORS[6]}'
,plot_bgcolor=f'rgb{VTB_COLORS[6]}'
,title='Распределение hh-индекса по регионам и данные росстата', title_x=0.5
,margin=dict(l=2,r=2)
# ,width=st.get_container_width
,height=500
)
fig = go.Figure(layout=layout)
fig.update_layout(
legend=dict(
yanchor="top",
y=0.99,
xanchor="center",
x=0.51
)
)
fig.add_trace(go.Scatter(x=lower.index, y=lower.values, line_color=blue_color_str,
name=f'({quantiles[0]}, {quantiles[2]}) квантили распр. по регионам'))
# fig.add_trace(go.Scatter(x=median.index, y=median.values, fill='tonexty', line_color='blue',
# name=f'{quantiles[1]}-ый квантиль'))
fig.add_trace(go.Scatter(x=upper.index, y=upper.values, fill='tonexty', line_color=blue_color_str
,showlegend=False))
fig.add_trace(go.Scatter(x=hh_index_df['date'], y=hh_index_df['hh_index'], line_color=lightblue_color_str,
name='hh индекс по всей России'))
fig.add_trace(go.Scatter(x=ros_df['date'], y=ros_df['unemp'], line_color=rosstat_color_str,
name='уровень безработицы (%), Росстат'))
st.plotly_chart(fig, use_container_width=True)
fig.write_image('pic.svg')
print('wrote')
st.write('После фераля hh-индекс резко вырос (на 30% м/м в марте и потом еще на на 16% м/м в апреле), но уровень беззработицы по данным Росстата продолжил снижение.')
st.write('Регионы с наибольшей безработицей по версии hh.ru')
# sort regions by force
show_df.sort_values(by=['hh_index'], inplace=True, ascending=False)
def get_headtail(df: pd.DataFrame, num: int = 5) -> pd.DataFrame:
cols = df.columns
dots_df = pd.DataFrame([['...'] * len(cols)], columns=cols, index=['...'])
ans_df = pd.concat([df.head(num), dots_df, df.tail(num)], axis=0)
for col in ans_df.columns:
ans_df[col] = ans_df[col].astype(str)
ans_df.index = ans_df.index.astype(str)
return ans_df
# cur_show = get_headtail(show_df[['date', 'name', 'hh_index', 'hh_index_change']].drop_duplicates().dropna(), 4)
cur_show = show_df[['date', 'name', 'hh_index', 'hh_index_change']].drop_duplicates().dropna()
cur_show.columns=['дата', 'регион', 'hh-индекс', 'изменение hh-индекса, % м/м']
cur_show['hh-индекс'] = cur_show['hh-индекс'].apply(lambda x: '%.1f' % x)
for col in ['изменение hh-индекса, % м/м']:
cur_show[col] = cur_show[col].apply(lambda x: '%.0f' % x)
cur_show['дата'] = cur_show['дата'].apply(lambda x: x.strftime('%Y-%m-%d'))
st.dataframe(cur_show, width=8000)
st.write('За последние 3 месяца hh-индекс вырос сильнее всего в Московской, Нижегородской, Тверской, Самарской, Калмыцкой, Пермской и Рязанской областях.')
st.write('В то же время за эти же 3 месяца он сократился в Респ. Тыва, Алтайской респ, Магаданской обл., Чукотке, Еврейском АО, Ингушетии и на Камчатке.')
temp="""
st.dataframe(show_df.dropna())
# fig.show()
# sl = st.slider('Дата', min_value=min_date, max_value=max_date, value=date)
# unemployment delta by region
# percentage increased/decreased
(prev_date, cur_date) = st.slider('2-range', min_value=min_date.to_pydatetime(),
max_value=max_date.to_pydatetime(),
value=(max_date.to_pydatetime() - timedelta(days=30),
max_date.to_pydatetime()), step=timedelta(days=30),
format="M'YY")
prev_date, cur_date = map(drop_day, [prev_date, cur_date])
color_good = tuple((np.array(VTB_COLORS[1]) * 255).astype(int))
color_bad = tuple((np.array(VTB_COLORS[3]) * 255).astype(int))
show_df = prof_df[['name', 'hh_index', 'date']][(prof_df['date'] == prev_date) | (prof_df['date'] == cur_date)]
show_df.to_excel('temp.xlsx', index=False)
st.dataframe(show_df)
st.write(f'Values: {prev_date, cur_date}')
"""
temp="""
st.write('stats df')
stats_df['prof_id'] = stats_df['prof_id'].astype(str)
st.dataframe(stats_df)
"""
temp="""
# salary distribution by specialization and prof area
# top skills
"""