From 47740d6600edfb6c3bac92b6831d18c539c200fa Mon Sep 17 00:00:00 2001 From: timofejmalinin Date: Wed, 16 Nov 2022 00:34:33 +0400 Subject: [PATCH] export fix --- service/utils.py | 20 ++++++---- service/views.py | 96 +++++++++++++++++++++++++++++------------------- 2 files changed, 72 insertions(+), 44 deletions(-) diff --git a/service/utils.py b/service/utils.py index 6147081..f7cd975 100644 --- a/service/utils.py +++ b/service/utils.py @@ -8,7 +8,7 @@ def raschet_real(df, koefs): df['rate'] = df['rate'] / koef_summ return df -def raschet(tables, filters, koefs): +def raschet(tables, filters, koefs, method): conn = sqlalchemy.create_engine(settings.DB_URL, connect_args={'options': '-csearch_path=public'}) msk_ao = filters.get('msk_ao') msk_rayon = filters.get('msk_rayon') @@ -27,9 +27,12 @@ def raschet(tables, filters, koefs): else: query = f"select * from {table} where category in ({categories});" if len(categories) > 0 else f"select * from {table};" points = pd.read_sql(query, conn) - points_df = raschet_real(points, koefs) - if rate_from is not None and rate_to is not None: - points_df = points_df[(points_df['rate'] >= rate_from) & (points_df['rate'] <= rate_to)] + if method == 'rate': + points_df = raschet_real(points, koefs) + if rate_from is not None and rate_to is not None: + points_df = points_df[(points_df['rate'] >= rate_from) & (points_df['rate'] <= rate_to)] + else: + points_df = points[(points['model'] >= rate_from) & (points['model'] <= rate_to)] if 'net' in table: if msk_ao is not None: @@ -39,8 +42,11 @@ def raschet(tables, filters, koefs): else: query = f"select * from {table};" nets = pd.read_sql(query, conn) - nets_df = raschet_real(nets, koefs) - if rate_from is not None and rate_to is not None: - nets_df = nets_df[(nets_df['rate'] >= rate_from) & (nets_df['rate'] <= rate_to)] + if method == 'rate': + nets_df = raschet_real(nets, koefs) + if rate_from is not None and rate_to is not None: + nets_df = nets_df[(nets_df['rate'] >= rate_from) & (nets_df['rate'] <= rate_to)] + else: + nets_df = nets[(nets['model'] >= rate_from) & (nets['model'] <= rate_to)] return points_df, nets_df diff --git a/service/views.py b/service/views.py index 77b5a3f..a16ef37 100644 --- a/service/views.py +++ b/service/views.py @@ -31,61 +31,83 @@ class raschet(GenericAPIView): def post(self, request, format=None): POINTS_RENAME_DICT = { "point_id": "ID точки (для всех наборов одинаковые)", - "category": "тип объекта", + "category": "Тип объекта", "msk_ao": "Адм. округ", "msk_rayon": "Адм. район", - "people": "Численность населения в 2021 г.", - "people2025": "Численность населения в 2025 г. (прогноз)", - "stops_ot": "Остановки общественного транспорта", - "routes_ot": "Маршруты общетвенного транспорта", - "in_metro": "Входы в ближайшее метро в месяц", - "out_metro": "Выходы из ближайшего метро в месяц", - "tc": "Тогровые центры", - "empls": "Рабочие места", - "walkers": "Трафик населения", - "schools": "Школы и детские сады", - "parking": "Парковочные места", - "pvz": "Пункты выдачи заказов", - "gov_place": "Рекомендованные пункты размещения постаматов", - "bike_park": "Городская аренда велосипедов, шт.", - "products": "Продовольственные магазины", - "nonprod": "Непродовольственные магазины", - "service": "Пункты оказания бытовых услуг", - "vuz": "ВУЗы и техникумы" + "addr": "Адрес", + "name": "Название", + "model": "Модель на ML", + "rate": "Стандартная модель", } NET_RENAME_DICT = { "cell_id": "ID ячейки (для всех трёх сеток - разные, нумерация сквозная)", "msk_ao": "Адм. округ", "msk_rayon": "Адм. район", - "people": "Численность населения в 2021 г.", - "people2025": "Численность населения в 2025 г. (прогноз)", - "stops_ot": "Остановки общественного транспорта", - "routes_ot": "Маршруты общетвенного транспорта", - "in_metro": "Входы в ближайшее метро в месяц", - "out_metro": "Выходы из ближайшего метро в месяц", - "tc": "Тогровые центры", - "empls": "Рабочие места", - "walkers": "Трафик населения", - "schools": "Школы и детские сады", - "parking": "Парковочные места", - "pvz": "Пункты выдачи заказов", - "gov_place": "Рекомендованные пункты размещения постаматов", - "bike_park": "Городская аренда велосипедов, шт.", - "products": "Продовольственные магазины", - "nonprod": "Непродовольственные магазины", - "service": "Пункты оказания бытовых услуг", - "vuz": "ВУЗы и техникумы" + "vuz": "ВУЗы и техникумы", + "model": "Модель на ML", + "rate": "Стандартная модель", } + TIPES_DICT = { + "kiosk": "городской киоск", + "mfc": "МФЦ", + "library": "библиотека", + "dk": "дом культуры и клуб", + "sport": "спортивный объект", + } + RAYONS_RENAME_DICT = {1: 'район Филёвский Парк', 2: 'район Зюзино', 3: 'район Внуково', 4: 'Алтуфьевский район', 5: 'Дмитровский район', 6: 'Можайский район', 7: 'район Ново-Переделкино', 8: 'район Щукино', 9: 'Молжаниновский район', 10: 'район Митино', 11: 'район Куркино', 12: 'район Аэропорт', 13: 'район Строгино', 14: 'район Крылатское', 15: 'район Тёплый Стан', 16: 'район Солнцево', 57: 'Бутырский район', 17: 'район Южное Тушино', 18: 'район Северное Тушино', 19: 'район Покровское-Стрешнево', 20: 'район Хорошёво-Мнёвники', 21: 'район Очаково-Матвеевское', 22: 'район Тропарёво-Никулино', 23: 'район Левобережный', 24: 'район Фили-Давыдково', 25: 'район Ховрино', 26: 'Головинский район', 27: 'район Раменки', 28: 'Войковский район', 29: 'район Западное Дегунино', 30: 'район Сокол', 31: 'район Проспект Вернадского', 32: 'район Южное Бутово', 33: 'Обручевский район', 34: 'район Ясенево', 35: 'район Дорогомилово', 36: 'район Коньково', 37: 'Хорошёвский район', 38: 'район Северный', 39: 'район Коптево', 40: 'Ломоносовский район', 58: 'район Марфино', 59: 'Тверской район', 41: 'Пресненский район', 74: 'район Нагатино-Садовники', 42: 'Бескудниковский район', 43: 'Гагаринский район', 44: 'район Черёмушки', 45: 'Тимирязевский район', 46: 'район Беговой', 47: 'район Хамовники', 48: 'район Северное Бутово', 49: 'район Лианозово', 50: 'район Восточное Дегунино', 51: 'Савёловский район', 52: 'Академический район', 53: 'район Чертаново Центральное', 54: 'район Отрадное', 55: 'район Арбат', 56: 'район Чертаново Южное', 60: 'район Чертаново Северное', 61: 'район Якиманка', 62: 'район Котловка', 63: 'Останкинский район', 64: 'Донской район', 65: 'район Бибирево', 66: 'район Марьина Роща', 67: 'Нагорный район', 68: 'Даниловский район', 73: 'район Северное Медведково', 69: 'Мещанский район', 70: 'район Бирюлёво Западное', 71: 'район Южное Медведково', 72: 'район Замоскворечье', 75: 'район Царицыно', 76: 'район Москворечье-Сабурово', 77: 'район Свиблово', 78: 'район Нагатинский Затон', 82: 'Таганский район', 79: 'Басманный район', 80: 'Красносельский район', 81: 'район Ростокино', 83: 'Алексеевский район', 84: 'район Восточный', 87: 'Бабушкинский район', 85: 'район Бирюлёво Восточное', 86: 'Южнопортовый район', 88: 'район Сокольники', 89: 'Ярославский район', 90: 'район Богородское', 91: 'район Метрогородок', 92: 'район Лефортово', 93: 'район Орехово-Борисово Северное', 94: 'район Печатники', 95: 'Лосиноостровский район', 98: 'район Новогиреево', 96: 'Нижегородский район', 99: 'район Марьино', 97: 'район Орехово-Борисово Южное', 100: 'район Преображенское', 105: 'район Братеево', 101: 'район Соколиная Гора', 102: 'район Перово', 103: 'район Люблино', 104: 'район Текстильщики', 106: 'район Зябликово', 107: 'Рязанский район', 108: 'район Измайлово', 109: 'район Северное Измайлово', 113: 'район Капотня', 110: 'район Кузьминки', 111: 'район Гольяново', 112: 'район Вешняки', 114: 'район Выхино-Жулебино', 115: 'район Восточное Измайлово', 118: 'район Новокосино', 116: 'район Ивановское', 117: 'район Косино-Ухтомский', 119: 'район Некрасовка', 120: 'район Кунцево'} + AO_RENAME_DICT = {1: 'Западный административный округ', 2: 'Южный административный округ', 3: 'Северный административный округ', 4: 'Юго-Западный административный округ', 5: 'Северо-Западный административный округ', 6: 'Центральный административный округ', 7: 'Северо-Восточный административный округ', 8: 'Юго-Восточный административный округ', 9: 'Восточный административный округ'} + EXCLUDED_COLS = ['id', 'people', 'people2025', 'stops_ot', 'routes_ot', 'in_metro', 'out_metro', 'tc', 'empls', 'walkers', 'schools', 'parking', 'pvz', 'gov_place', 'bike_park', 'products', 'nonprod', 'service', 'vuz'] df_points_, df_nets_ = raschet_alg(**request.data) + df_points_['category'] = df_points_['category'].map(TIPES_DICT) + df_points_['msk_ao'] = df_points_['msk_ao'].map(AO_RENAME_DICT) + df_points_['msk_rayon'] = df_points_['msk_rayon'].map(RAYONS_RENAME_DICT) + df_nets_['msk_ao'] = df_nets_['msk_ao'].map(AO_RENAME_DICT) + df_nets_['msk_rayon'] = df_nets_['msk_rayon'].map(RAYONS_RENAME_DICT) + df_points_ = df_points_.drop(columns=EXCLUDED_COLS) + df_nets_ = df_nets_.drop(columns=EXCLUDED_COLS) + df_points = rename_result_dataset(df_points_, POINTS_RENAME_DICT) + if "Стандартная модель" in df_points.columns: + df_points = df_points[["ID точки (для всех наборов одинаковые)", "Адм. округ", "Адм. район", "Адрес", "Название", "Тип объекта", "geom", "Модель на ML", "Стандартная модель"]] + else: + df_points = df_points[["ID точки (для всех наборов одинаковые)", "Адм. округ", "Адм. район", "Адрес", "Название", "Тип объекта", "geom", "Модель на ML",]] + + + df_nets = rename_result_dataset(df_nets_, NET_RENAME_DICT) + if "Стандартная модель" in df_nets.columns: + df_nets = df_nets[["ID ячейки (для всех трёх сеток - разные, нумерация сквозная)", "Адм. округ", "Адм. район", "geom", "Модель на ML", "Стандартная модель"]] + else: + df_nets = df_nets[["ID ячейки (для всех трёх сеток - разные, нумерация сквозная)", "Адм. округ", "Адм. район", "geom", "Модель на ML"]] + + with BytesIO() as b: # Use the StringIO object as the filehandle. writer = pd.ExcelWriter(b, engine='xlsxwriter') if df_points is not None: df_points.to_excel(writer, sheet_name='Точки', index=False) + worksheet = writer.sheets['Точки'] # pull worksheet object + for idx, col in enumerate(df_points): # loop through all columns + if col == 'geom': + continue + series = df_points[col] + max_len = max(( + series.astype(str).map(len).max(), # len of largest item + len(str(series.name)) # len of column name/header + )) + 1 # adding a little extra space + worksheet.set_column(idx, idx, max_len) if df_nets is not None: df_nets.to_excel(writer, sheet_name='Полигоны', index=False) + worksheet = writer.sheets['Полигоны'] # pull worksheet object + for idx, col in enumerate(df_nets): # loop through all columns + if col == 'geom': + continue + series = df_nets[col] + max_len = max(( + series.astype(str).map(len).max(), # len of largest item + len(str(series.name)) # len of column name/header + )) + 1 # adding a little extra space + worksheet.set_column(idx, idx, max_len) writer.save() # Set up the Http response. filename = f'Выгрузка.xlsx'