{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import pandas as pd\n", "import numpy as np\n", "import os\n", "import sumolib\n", "import random\n", "from tqdm import tqdm\n", "from datetime import datetime" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# A. 이동류 매칭" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 17280/17280 [00:13<00:00, 1248.15it/s]\n" ] }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
inter_nophas_Aphas_Bmove_Amove_B
01751184
11752273
21753361
31753462
41754452
51761184
61762283
717633518
81771184
91772273
\n", "
" ], "text/plain": [ " inter_no phas_A phas_B move_A move_B\n", "0 175 1 1 8 4\n", "1 175 2 2 7 3\n", "2 175 3 3 6 1\n", "3 175 3 4 6 2\n", "4 175 4 4 5 2\n", "5 176 1 1 8 4\n", "6 176 2 2 8 3\n", "7 176 3 3 5 18\n", "8 177 1 1 8 4\n", "9 177 2 2 7 3" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# [이동류번호] 불러오기 (약 1분의 소요시간)\n", "path_moves = '../../Data/tables/moves/'\n", "csv_moves = os.listdir('../../Data/tables/moves/')\n", "moves = [pd.read_csv(path_moves + csv_move, index_col=0) for csv_move in tqdm(csv_moves)]\n", "match1 = pd.concat(moves).drop_duplicates().sort_values(by=['inter_no','phas_A','phas_B']).reset_index(drop=True)\n", "match1.head(10)" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
inter_nophase_noring_typemove_no
01751A8
01751B4
11752A7
11752B3
21753A6
21753B1
41754A5
31754B2
51761A8
51761B4
\n", "
" ], "text/plain": [ " inter_no phase_no ring_type move_no\n", "0 175 1 A 8\n", "0 175 1 B 4\n", "1 175 2 A 7\n", "1 175 2 B 3\n", "2 175 3 A 6\n", "2 175 3 B 1\n", "4 175 4 A 5\n", "3 175 4 B 2\n", "5 176 1 A 8\n", "5 176 1 B 4" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 계층화 (inter_no, phas_A, phas_B, move_A, move_B) -> ('inter_no', 'phase_no', 'ring_type', 'move_no')\n", "matchA = match1[['inter_no', 'phas_A', 'move_A']].copy()\n", "matchA.columns = ['inter_no', 'phase_no', 'move_no']\n", "matchA['ring_type'] = 'A'\n", "matchB = match1[['inter_no', 'phas_B', 'move_B']].copy()\n", "matchB.columns = ['inter_no', 'phase_no', 'move_no']\n", "matchB['ring_type'] = 'B'\n", "match2 = pd.concat([matchA, matchB]).drop_duplicates()\n", "match2 = match2[['inter_no', 'phase_no', 'ring_type', 'move_no']]\n", "match2 = match2.sort_values(by=list(match2.columns))\n", "match2.head(10)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
inter_nophase_noring_typemove_noinc_dirout_dir
01751A8
11751B4
21752A7
31752B3
41753A6
51753B1
61754A5
71754B2
81761A8
91761B4
101762A8
111762B3
121763A5
131763B18NaNNaN
141771A8
151771B4
161772A7
171772B3
181773A17NaNNaN
191773B18NaNNaN
201774A5
211774B1
221781A8
231781B4
241782A7
251782B3
261783A5
271783B2
281784A6
291784B1
302011A8
312011B3
322012A5
332012B2
342013A6
352013B2
362014A6
372014B1
382015A7
392015B4
402021A6
412021B2
422022A17NaNNaN
432022B18NaNNaN
442061A8
452061B4
462062A17NaNNaN
472062B18NaNNaN
482063A8
492063B4
502064A17NaNNaN
512064B18NaNNaN
522101A6
532101B18NaNNaN
542102A5
552102B2
562103A7
572103B4
582104A8
592104B3
\n", "
" ], "text/plain": [ " inter_no phase_no ring_type move_no inc_dir out_dir\n", "0 175 1 A 8 남 북\n", "1 175 1 B 4 북 남\n", "2 175 2 A 7 북 동\n", "3 175 2 B 3 남 서\n", "4 175 3 A 6 동 서\n", "5 175 3 B 1 동 남\n", "6 175 4 A 5 서 북\n", "7 175 4 B 2 서 동\n", "8 176 1 A 8 남 북\n", "9 176 1 B 4 북 남\n", "10 176 2 A 8 남 북\n", "11 176 2 B 3 남 서\n", "12 176 3 A 5 서 북\n", "13 176 3 B 18 NaN NaN\n", "14 177 1 A 8 남 북\n", "15 177 1 B 4 북 남\n", "16 177 2 A 7 북 동\n", "17 177 2 B 3 남 서\n", "18 177 3 A 17 NaN NaN\n", "19 177 3 B 18 NaN NaN\n", "20 177 4 A 5 서 북\n", "21 177 4 B 1 동 남\n", "22 178 1 A 8 남 북\n", "23 178 1 B 4 북 남\n", "24 178 2 A 7 북 동\n", "25 178 2 B 3 남 서\n", "26 178 3 A 5 서 북\n", "27 178 3 B 2 서 동\n", "28 178 4 A 6 동 서\n", "29 178 4 B 1 동 남\n", "30 201 1 A 8 남 북\n", "31 201 1 B 3 남 서\n", "32 201 2 A 5 서 북\n", "33 201 2 B 2 서 동\n", "34 201 3 A 6 동 서\n", "35 201 3 B 2 서 동\n", "36 201 4 A 6 동 서\n", "37 201 4 B 1 동 남\n", "38 201 5 A 7 북 동\n", "39 201 5 B 4 북 남\n", "40 202 1 A 6 동 서\n", "41 202 1 B 2 서 동\n", "42 202 2 A 17 NaN NaN\n", "43 202 2 B 18 NaN NaN\n", "44 206 1 A 8 남 북\n", "45 206 1 B 4 북 남\n", "46 206 2 A 17 NaN NaN\n", "47 206 2 B 18 NaN NaN\n", "48 206 3 A 8 남 북\n", "49 206 3 B 4 북 남\n", "50 206 4 A 17 NaN NaN\n", "51 206 4 B 18 NaN NaN\n", "52 210 1 A 6 동 서\n", "53 210 1 B 18 NaN NaN\n", "54 210 2 A 5 서 북\n", "55 210 2 B 2 서 동\n", "56 210 3 A 7 북 동\n", "57 210 3 B 4 북 남\n", "58 210 4 A 8 남 북\n", "59 210 4 B 3 남 서" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# [nema 이동류목록] 불러오기 및 병합\n", "nema = pd.read_csv('../../Data/tables/nema.csv', encoding='cp949')\n", "match3 = pd.merge(match2, nema, how='left', on='move_no').drop_duplicates()\n", "match3" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
inter_nophase_noring_typemove_noinc_dirout_dirinc_angleout_angle
01751A8179004
11751B4003176
21752A7001095
31752B3179270
41753A6090270
51753B1090180
61754A5268000
71754B2270090
81761A8180000
91761B4359180
101762A8180000
111762B3180270
121763A5270356
131763B18NaNNaNNaNNaN
141771A8180000
151771B4001176
161772A7000090
171772B3179270
181773A17NaNNaNNaNNaN
191773B18NaNNaNNaNNaN
201774A5268000
211774B1090180
221781A8180000
231781B4000180
241782A7000090
251782B3180270
261783A5270000
271783B2270090
281784A6090270
291784B1090180
302011A8180000
312011B3180270
322012A5270000
332012B2270090
342013A6090270
352013B2270090
362014A6090270
372014B1090180
382015A7000090
392015B4000180
402021A6090270
412021B2270090
422022A17NaNNaNNaNNaN
432022B18NaNNaNNaNNaN
442061A8180000
452061B4000180
462062A17NaNNaNNaNNaN
472062B18NaNNaNNaNNaN
482063A8180000
492063B4000180
502064A17NaNNaNNaNNaN
512064B18NaNNaNNaNNaN
522101A6090270
532101B18NaNNaNNaNNaN
542102A5268000
552102B2270090
562103A7359090
572103B4000180
582104A8180000
592104B3180270
\n", "
" ], "text/plain": [ " inter_no phase_no ring_type move_no inc_dir out_dir inc_angle out_angle\n", "0 175 1 A 8 남 북 179 004\n", "1 175 1 B 4 북 남 003 176\n", "2 175 2 A 7 북 동 001 095\n", "3 175 2 B 3 남 서 179 270\n", "4 175 3 A 6 동 서 090 270\n", "5 175 3 B 1 동 남 090 180\n", "6 175 4 A 5 서 북 268 000\n", "7 175 4 B 2 서 동 270 090\n", "8 176 1 A 8 남 북 180 000\n", "9 176 1 B 4 북 남 359 180\n", "10 176 2 A 8 남 북 180 000\n", "11 176 2 B 3 남 서 180 270\n", "12 176 3 A 5 서 북 270 356\n", "13 176 3 B 18 NaN NaN NaN NaN\n", "14 177 1 A 8 남 북 180 000\n", "15 177 1 B 4 북 남 001 176\n", "16 177 2 A 7 북 동 000 090\n", "17 177 2 B 3 남 서 179 270\n", "18 177 3 A 17 NaN NaN NaN NaN\n", "19 177 3 B 18 NaN NaN NaN NaN\n", "20 177 4 A 5 서 북 268 000\n", "21 177 4 B 1 동 남 090 180\n", "22 178 1 A 8 남 북 180 000\n", "23 178 1 B 4 북 남 000 180\n", "24 178 2 A 7 북 동 000 090\n", "25 178 2 B 3 남 서 180 270\n", "26 178 3 A 5 서 북 270 000\n", "27 178 3 B 2 서 동 270 090\n", "28 178 4 A 6 동 서 090 270\n", "29 178 4 B 1 동 남 090 180\n", "30 201 1 A 8 남 북 180 000\n", "31 201 1 B 3 남 서 180 270\n", "32 201 2 A 5 서 북 270 000\n", "33 201 2 B 2 서 동 270 090\n", "34 201 3 A 6 동 서 090 270\n", "35 201 3 B 2 서 동 270 090\n", "36 201 4 A 6 동 서 090 270\n", "37 201 4 B 1 동 남 090 180\n", "38 201 5 A 7 북 동 000 090\n", "39 201 5 B 4 북 남 000 180\n", "40 202 1 A 6 동 서 090 270\n", "41 202 1 B 2 서 동 270 090\n", "42 202 2 A 17 NaN NaN NaN NaN\n", "43 202 2 B 18 NaN NaN NaN NaN\n", "44 206 1 A 8 남 북 180 000\n", "45 206 1 B 4 북 남 000 180\n", "46 206 2 A 17 NaN NaN NaN NaN\n", "47 206 2 B 18 NaN NaN NaN NaN\n", "48 206 3 A 8 남 북 180 000\n", "49 206 3 B 4 북 남 000 180\n", "50 206 4 A 17 NaN NaN NaN NaN\n", "51 206 4 B 18 NaN NaN NaN NaN\n", "52 210 1 A 6 동 서 090 270\n", "53 210 1 B 18 NaN NaN NaN NaN\n", "54 210 2 A 5 서 북 268 000\n", "55 210 2 B 2 서 동 270 090\n", "56 210 3 A 7 북 동 359 090\n", "57 210 3 B 4 북 남 000 180\n", "58 210 4 A 8 남 북 180 000\n", "59 210 4 B 3 남 서 180 270" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# [방위각정보] 불러오기, 계층화, 병합\n", "# 불러오기\n", "dtype_dict = {f'angle_{alph}{j}':'str' for alph in ['A', 'B'] for j in range(1,9)}\n", "angle_original = pd.read_csv('../../Data/tables/angle.csv', index_col=0, dtype = dtype_dict)\n", "# 계층화\n", "angle = []\n", "for i, row in angle_original.iterrows():\n", " angle_codes = row[[f'angle_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]]\n", " new = pd.DataFrame({'inter_no':[row.inter_no] * 16, 'phase_no':list(range(1, 9))*2, 'ring_type':['A'] * 8 + ['B'] * 8, 'angle_code':angle_codes.to_list()})\n", " angle.append(new)\n", "angle = pd.concat(angle)\n", "angle = angle.dropna().reset_index(drop=True)\n", "# 병합\n", "six_chars = angle.angle_code.apply(lambda x:len(x)==6)\n", "angle.loc[six_chars,'inc_angle'] = angle.angle_code.apply(lambda x:x[:3])\n", "angle.loc[six_chars,'out_angle'] = angle.angle_code.apply(lambda x:x[3:])\n", "angle = angle.drop('angle_code', axis=1)\n", "match4 = pd.merge(match3, angle, how='left', left_on=['inter_no', 'phase_no', 'ring_type'],\n", " right_on=['inter_no', 'phase_no', 'ring_type']).drop_duplicates()\n", "match4" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
inter_nophase_noring_typemove_noinc_dirout_dirinc_angleout_angleinc_edgeout_edgenode_id
01753B1090180571545870_02571542797_02i0
11754B2270090571510153_02571545870_01i0
21752B3179270-571542797_02571510153_01i0
31751B4003176-571500487_01571542797_02i0
41754A5268000571510153_02571500487_01i0
51753A6090270571545870_02571510153_01i0
61752A7001095-571500487_01571545870_01i0
71751A8179004-571542797_02571500487_01i0
81762B3180270-571542810_01571543469_01i1
91761B4359180571542797_02.99571542810_01i1
101763A5270356571543469_02-571542797_02.99i1
111761A8180000-571542810_01-571542797_02.99i1
121762A8180000-571542810_01-571542797_02.99i1
131763B18NaNNaNNaNNaNNaNNaNi1
141774B1090180571542107_02571542809_01i2
151772B3179270-571542809_01571542809_01i2
161771B4001176571542811_02571542809_01i2
171774A5268000-571542809_01571542811_01i2
181772A7000090571542811_02571542107_01i2
191771A8180000-571542809_01571542811_01i2
201773A17NaNNaNNaNNaNNaNNaNi2
211773B18NaNNaNNaNNaNNaNNaNi2
221784B1090180-571500475_01571540304_01i3
231783B2270090571540303_02.21571500475_01i3
241782B3180270571540304_02571540303_01i3
251781B4000180571556450_02571540304_01i3
261783A5270000571540303_02.21571556450_01i3
271784A6090270-571500475_01571540303_01i3
281782A7000090571556450_02571500475_01i3
291781A8180000571540304_02571556450_01i3
302014B1090180571500617_02571500569_01i8
312012B2270090571500618_02571500617_01i8
322013B2270090571500618_02571500617_01i8
332011B3180270-571500569_01571500618_01i8
342015B4000180571500583_01571500569_01i8
352012A5270000571500618_02571500583_02i8
362013A6090270571500617_02571500618_01i8
372014A6090270571500617_02571500618_01i8
382015A7000090571500583_01571500617_01i8
392011A8180000-571500569_01571500583_02i8
402021B2270090571510152_01571510152_01.65i9
412021A6090270571510152_02-571510152_01i9
422022A17NaNNaNNaNNaNNaNNaNi9
432022B18NaNNaNNaNNaNNaNNaNi9
442061B4000180571542073_01571511538_02i7
452063B4000180571542073_01571511538_02i7
462061A8180000-571511538_02571542073_02i7
472063A8180000-571511538_02571542073_02i7
482062A17NaNNaNNaNNaNNaNNaNi7
492064A17NaNNaNNaNNaNNaNNaNi7
502062B18NaNNaNNaNNaNNaNNaNi7
512064B18NaNNaNNaNNaNNaNNaNi7
522102B2270090571500535_02.18571542115_01i6
532104B3180270571500585_02571500535_01i6
542103B4000180571511538_02.121571500585_01i6
552102A5268000571500535_02.18571511538_01i6
562101A6090270-571542115_01571500535_01i6
572103A7359090571511538_02.121571542115_01i6
582104A8180000571500585_02571511538_01i6
592101B18NaNNaNNaNNaNNaNNaNi6
\n", "
" ], "text/plain": [ " inter_no phase_no ring_type move_no inc_dir out_dir inc_angle out_angle \\\n", "0 175 3 B 1 동 남 090 180 \n", "1 175 4 B 2 서 동 270 090 \n", "2 175 2 B 3 남 서 179 270 \n", "3 175 1 B 4 북 남 003 176 \n", "4 175 4 A 5 서 북 268 000 \n", "5 175 3 A 6 동 서 090 270 \n", "6 175 2 A 7 북 동 001 095 \n", "7 175 1 A 8 남 북 179 004 \n", "8 176 2 B 3 남 서 180 270 \n", "9 176 1 B 4 북 남 359 180 \n", "10 176 3 A 5 서 북 270 356 \n", "11 176 1 A 8 남 북 180 000 \n", "12 176 2 A 8 남 북 180 000 \n", "13 176 3 B 18 NaN NaN NaN NaN \n", "14 177 4 B 1 동 남 090 180 \n", "15 177 2 B 3 남 서 179 270 \n", "16 177 1 B 4 북 남 001 176 \n", "17 177 4 A 5 서 북 268 000 \n", "18 177 2 A 7 북 동 000 090 \n", "19 177 1 A 8 남 북 180 000 \n", "20 177 3 A 17 NaN NaN NaN NaN \n", "21 177 3 B 18 NaN NaN NaN NaN \n", "22 178 4 B 1 동 남 090 180 \n", "23 178 3 B 2 서 동 270 090 \n", "24 178 2 B 3 남 서 180 270 \n", "25 178 1 B 4 북 남 000 180 \n", "26 178 3 A 5 서 북 270 000 \n", "27 178 4 A 6 동 서 090 270 \n", "28 178 2 A 7 북 동 000 090 \n", "29 178 1 A 8 남 북 180 000 \n", "30 201 4 B 1 동 남 090 180 \n", "31 201 2 B 2 서 동 270 090 \n", "32 201 3 B 2 서 동 270 090 \n", "33 201 1 B 3 남 서 180 270 \n", "34 201 5 B 4 북 남 000 180 \n", "35 201 2 A 5 서 북 270 000 \n", "36 201 3 A 6 동 서 090 270 \n", "37 201 4 A 6 동 서 090 270 \n", "38 201 5 A 7 북 동 000 090 \n", "39 201 1 A 8 남 북 180 000 \n", "40 202 1 B 2 서 동 270 090 \n", "41 202 1 A 6 동 서 090 270 \n", "42 202 2 A 17 NaN NaN NaN NaN \n", "43 202 2 B 18 NaN NaN NaN NaN \n", "44 206 1 B 4 북 남 000 180 \n", "45 206 3 B 4 북 남 000 180 \n", "46 206 1 A 8 남 북 180 000 \n", "47 206 3 A 8 남 북 180 000 \n", "48 206 2 A 17 NaN NaN NaN NaN \n", "49 206 4 A 17 NaN NaN NaN NaN \n", "50 206 2 B 18 NaN NaN NaN NaN \n", "51 206 4 B 18 NaN NaN NaN NaN \n", "52 210 2 B 2 서 동 270 090 \n", "53 210 4 B 3 남 서 180 270 \n", "54 210 3 B 4 북 남 000 180 \n", "55 210 2 A 5 서 북 268 000 \n", "56 210 1 A 6 동 서 090 270 \n", "57 210 3 A 7 북 동 359 090 \n", "58 210 4 A 8 남 북 180 000 \n", "59 210 1 B 18 NaN NaN NaN NaN \n", "\n", " inc_edge out_edge node_id \n", "0 571545870_02 571542797_02 i0 \n", "1 571510153_02 571545870_01 i0 \n", "2 -571542797_02 571510153_01 i0 \n", "3 -571500487_01 571542797_02 i0 \n", "4 571510153_02 571500487_01 i0 \n", "5 571545870_02 571510153_01 i0 \n", "6 -571500487_01 571545870_01 i0 \n", "7 -571542797_02 571500487_01 i0 \n", "8 -571542810_01 571543469_01 i1 \n", "9 571542797_02.99 571542810_01 i1 \n", "10 571543469_02 -571542797_02.99 i1 \n", "11 -571542810_01 -571542797_02.99 i1 \n", "12 -571542810_01 -571542797_02.99 i1 \n", "13 NaN NaN i1 \n", "14 571542107_02 571542809_01 i2 \n", "15 -571542809_01 571542809_01 i2 \n", "16 571542811_02 571542809_01 i2 \n", "17 -571542809_01 571542811_01 i2 \n", "18 571542811_02 571542107_01 i2 \n", "19 -571542809_01 571542811_01 i2 \n", "20 NaN NaN i2 \n", "21 NaN NaN i2 \n", "22 -571500475_01 571540304_01 i3 \n", "23 571540303_02.21 571500475_01 i3 \n", "24 571540304_02 571540303_01 i3 \n", "25 571556450_02 571540304_01 i3 \n", "26 571540303_02.21 571556450_01 i3 \n", "27 -571500475_01 571540303_01 i3 \n", "28 571556450_02 571500475_01 i3 \n", "29 571540304_02 571556450_01 i3 \n", "30 571500617_02 571500569_01 i8 \n", "31 571500618_02 571500617_01 i8 \n", "32 571500618_02 571500617_01 i8 \n", "33 -571500569_01 571500618_01 i8 \n", "34 571500583_01 571500569_01 i8 \n", "35 571500618_02 571500583_02 i8 \n", "36 571500617_02 571500618_01 i8 \n", "37 571500617_02 571500618_01 i8 \n", "38 571500583_01 571500617_01 i8 \n", "39 -571500569_01 571500583_02 i8 \n", "40 571510152_01 571510152_01.65 i9 \n", "41 571510152_02 -571510152_01 i9 \n", "42 NaN NaN i9 \n", "43 NaN NaN i9 \n", "44 571542073_01 571511538_02 i7 \n", "45 571542073_01 571511538_02 i7 \n", "46 -571511538_02 571542073_02 i7 \n", "47 -571511538_02 571542073_02 i7 \n", "48 NaN NaN i7 \n", "49 NaN NaN i7 \n", "50 NaN NaN i7 \n", "51 NaN NaN i7 \n", "52 571500535_02.18 571542115_01 i6 \n", "53 571500585_02 571500535_01 i6 \n", "54 571511538_02.121 571500585_01 i6 \n", "55 571500535_02.18 571511538_01 i6 \n", "56 -571542115_01 571500535_01 i6 \n", "57 571511538_02.121 571542115_01 i6 \n", "58 571500585_02 571511538_01 i6 \n", "59 NaN NaN i6 " ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# [네트워크], [교차로-노드 매칭], [교차로정보] 불러오기\n", "net = sumolib.net.readNet('../../Data/networks/SN_sample.net.xml')\n", "inter_node = pd.read_csv('../../Data/tables/inter_node.csv', index_col=0)\n", "inter_info = pd.read_csv('../../Data/tables/inter_info.csv', index_col=0)\n", "\n", "inter_node1 = inter_node[inter_node.inter_type == 'parent'].drop('inter_type', axis=1)\n", "inter_info1 = inter_info[['inter_no', 'inter_lat', 'inter_lon']]\n", "inter = pd.merge(inter_node1, inter_info1, how='left', left_on=['inter_no'],\n", " right_on=['inter_no']).drop_duplicates()\n", "\n", "inter2node = dict(zip(inter['inter_no'], inter['node_id']))\n", "\n", "match5 = match4.copy()\n", "# 진입진출ID 매칭\n", "for index, row in match5.iterrows():\n", " node_id = inter2node[row.inter_no]\n", " node = net.getNode(node_id)\n", " # 교차로의 모든 (from / to) edges\n", " inc_edges = [edge for edge in node.getIncoming() if edge.getFunction() == ''] # incoming edges\n", " out_edges = [edge for edge in node.getOutgoing() if edge.getFunction() == ''] # outgoing edges\n", " # 교차로의 모든 (from / to) directions\n", " inc_dirs = []\n", " for inc_edge in inc_edges:\n", " start = inc_edge.getShape()[-2]\n", " end = inc_edge.getShape()[-1]\n", " inc_dir = np.array(end) - np.array(start)\n", " inc_dir = inc_dir / (inc_dir ** 2).sum() ** 0.5\n", " inc_dirs.append(inc_dir)\n", " out_dirs = []\n", " for out_edge in out_edges:\n", " start = out_edge.getShape()[0]\n", " end = out_edge.getShape()[1]\n", " out_dir = np.array(end) - np.array(start)\n", " out_dir = out_dir / (out_dir ** 2).sum() ** 0.5\n", " out_dirs.append(out_dir)\n", " # 진입각, 진출각 불러오기\n", " if not pd.isna(row.inc_angle):\n", " inc_angle = int(row.inc_angle)\n", " out_angle = int(row.out_angle)\n", " # 방위각을 일반각으로 가공, 라디안 변환, 단위벡터로 변환\n", " inc_angle = (-90 - inc_angle) % 360\n", " inc_angle = inc_angle * np.pi / 180.\n", " inc_dir_true = np.array([np.cos(inc_angle), np.sin(inc_angle)])\n", " out_angle = (90 - out_angle) % 360\n", " out_angle = out_angle * np.pi / 180.\n", " out_dir_true = np.array([np.cos(out_angle), np.sin(out_angle)])\n", " # 매칭 엣지 반환\n", " inc_index = np.array([np.dot(inc_dir, inc_dir_true) for inc_dir in inc_dirs]).argmax()\n", " out_index = np.array([np.dot(out_dir, out_dir_true) for out_dir in out_dirs]).argmax()\n", " inc_edge_id = inc_edges[inc_index].getID()\n", " out_edge_id = out_edges[out_index].getID()\n", " match5.at[index, 'inc_edge'] = inc_edge_id\n", " match5.at[index, 'out_edge'] = out_edge_id\n", "match5['node_id'] = match5['inter_no'].map(inter2node)\n", "# match5 = match5[['inter_no', 'node_id', 'move_no', 'inc_edge', 'out_edge']]\n", "match5 = match5.sort_values(by=['inter_no', 'move_no']).reset_index(drop=True)\n", "match5" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
inter_nomove_noinc_dirout_dirinc_edgeout_edgenode_id
01751571545870_02571542797_02i0
11752571510153_02571545870_01i0
21753-571542797_02571510153_01i0
31754-571500487_01571542797_02i0
41755571510153_02571500487_01i0
51756571545870_02571510153_01i0
61757-571500487_01571545870_01i0
71758-571542797_02571500487_01i0
817517NoneNoneNoneNonei0
917518NoneNoneNoneNonei0
1017521-571500487_01571510153_01i0
1117521571510153_02571542797_02i0
1217521-571542797_02571545870_01i0
1317521571545870_02571500487_01i0
141763-571542810_01571543469_01i1
151764571542797_02.99571542810_01i1
161765571543469_02-571542797_02.99i1
171768-571542810_01-571542797_02.99i1
1817617NoneNoneNoneNonei1
1917618NoneNoneNoneNonei1
2017621571542797_02.99571543469_01i1
2117621571543469_02571542810_01i1
221771571542107_02571542809_01i2
231772-571542809_01571542107_01i2
241773-571542809_01571542809_01i2
251774571542811_02571542809_01i2
261775-571542809_01571542811_01i2
271776571542107_02571542809_01i2
281777571542811_02571542107_01i2
291778-571542809_01571542811_01i2
3017717NoneNoneNoneNonei2
3117718NoneNoneNoneNonei2
3217721571542811_02571542809_01i2
3317721-571542809_01571542809_01i2
3417721-571542809_01571542107_01i2
3517721571542107_02571542811_01i2
361781-571500475_01571540304_01i3
371782571540303_02.21571500475_01i3
381783571540304_02571540303_01i3
391784571556450_02571540304_01i3
401785571540303_02.21571556450_01i3
411786-571500475_01571540303_01i3
421787571556450_02571500475_01i3
431788571540304_02571556450_01i3
4417817NoneNoneNoneNonei3
4517818NoneNoneNoneNonei3
4617821571556450_02571540303_01i3
4717821571540303_02.21571540304_01i3
4817821571540304_02571500475_01i3
4917821-571500475_01571556450_01i3
502011571500617_02571500569_01i8
512012571500618_02571500617_01i8
522013-571500569_01571500618_01i8
532014571500583_01571500569_01i8
542015571500618_02571500583_02i8
552016571500617_02571500618_01i8
562017571500583_01571500617_01i8
572018-571500569_01571500583_02i8
5820117NoneNoneNoneNonei8
5920118NoneNoneNoneNonei8
6020121571500583_01571500618_01i8
6120121571500618_02571500569_01i8
6220121-571500569_01571500617_01i8
6320121571500617_02571500583_02i8
642022571510152_01571510152_01.65i9
652026571510152_02-571510152_01i9
6620217NoneNoneNoneNonei9
6720218NoneNoneNoneNonei9
682064571542073_01571511538_02i7
692068-571511538_02571542073_02i7
7020617NoneNoneNoneNonei7
7120618NoneNoneNoneNonei7
722101-571542115_01571500585_01i6
732102571500535_02.18571542115_01i6
742103571500585_02571500535_01i6
752104571511538_02.121571500585_01i6
762105571500535_02.18571511538_01i6
772106-571542115_01571500535_01i6
782107571511538_02.121571542115_01i6
792108571500585_02571511538_01i6
8021017NoneNoneNoneNonei6
8121018NoneNoneNoneNonei6
8221021571511538_02.121571500535_01i6
8321021571500535_02.18571500585_01i6
8421021571500585_02571542115_01i6
8521021-571542115_01571511538_01i6
\n", "
" ], "text/plain": [ " inter_no move_no inc_dir out_dir inc_edge out_edge \\\n", "0 175 1 동 남 571545870_02 571542797_02 \n", "1 175 2 서 동 571510153_02 571545870_01 \n", "2 175 3 남 서 -571542797_02 571510153_01 \n", "3 175 4 북 남 -571500487_01 571542797_02 \n", "4 175 5 서 북 571510153_02 571500487_01 \n", "5 175 6 동 서 571545870_02 571510153_01 \n", "6 175 7 북 동 -571500487_01 571545870_01 \n", "7 175 8 남 북 -571542797_02 571500487_01 \n", "8 175 17 None None None None \n", "9 175 18 None None None None \n", "10 175 21 북 서 -571500487_01 571510153_01 \n", "11 175 21 서 남 571510153_02 571542797_02 \n", "12 175 21 남 동 -571542797_02 571545870_01 \n", "13 175 21 동 북 571545870_02 571500487_01 \n", "14 176 3 남 서 -571542810_01 571543469_01 \n", "15 176 4 북 남 571542797_02.99 571542810_01 \n", "16 176 5 서 북 571543469_02 -571542797_02.99 \n", "17 176 8 남 북 -571542810_01 -571542797_02.99 \n", "18 176 17 None None None None \n", "19 176 18 None None None None \n", "20 176 21 북 서 571542797_02.99 571543469_01 \n", "21 176 21 서 남 571543469_02 571542810_01 \n", "22 177 1 동 남 571542107_02 571542809_01 \n", "23 177 2 서 동 -571542809_01 571542107_01 \n", "24 177 3 남 서 -571542809_01 571542809_01 \n", "25 177 4 북 남 571542811_02 571542809_01 \n", "26 177 5 서 북 -571542809_01 571542811_01 \n", "27 177 6 동 서 571542107_02 571542809_01 \n", "28 177 7 북 동 571542811_02 571542107_01 \n", "29 177 8 남 북 -571542809_01 571542811_01 \n", "30 177 17 None None None None \n", "31 177 18 None None None None \n", "32 177 21 북 서 571542811_02 571542809_01 \n", "33 177 21 서 남 -571542809_01 571542809_01 \n", "34 177 21 남 동 -571542809_01 571542107_01 \n", "35 177 21 동 북 571542107_02 571542811_01 \n", "36 178 1 동 남 -571500475_01 571540304_01 \n", "37 178 2 서 동 571540303_02.21 571500475_01 \n", "38 178 3 남 서 571540304_02 571540303_01 \n", "39 178 4 북 남 571556450_02 571540304_01 \n", "40 178 5 서 북 571540303_02.21 571556450_01 \n", "41 178 6 동 서 -571500475_01 571540303_01 \n", "42 178 7 북 동 571556450_02 571500475_01 \n", "43 178 8 남 북 571540304_02 571556450_01 \n", "44 178 17 None None None None \n", "45 178 18 None None None None \n", "46 178 21 북 서 571556450_02 571540303_01 \n", "47 178 21 서 남 571540303_02.21 571540304_01 \n", "48 178 21 남 동 571540304_02 571500475_01 \n", "49 178 21 동 북 -571500475_01 571556450_01 \n", "50 201 1 동 남 571500617_02 571500569_01 \n", "51 201 2 서 동 571500618_02 571500617_01 \n", "52 201 3 남 서 -571500569_01 571500618_01 \n", "53 201 4 북 남 571500583_01 571500569_01 \n", "54 201 5 서 북 571500618_02 571500583_02 \n", "55 201 6 동 서 571500617_02 571500618_01 \n", "56 201 7 북 동 571500583_01 571500617_01 \n", "57 201 8 남 북 -571500569_01 571500583_02 \n", "58 201 17 None None None None \n", "59 201 18 None None None None \n", "60 201 21 북 서 571500583_01 571500618_01 \n", "61 201 21 서 남 571500618_02 571500569_01 \n", "62 201 21 남 동 -571500569_01 571500617_01 \n", "63 201 21 동 북 571500617_02 571500583_02 \n", "64 202 2 서 동 571510152_01 571510152_01.65 \n", "65 202 6 동 서 571510152_02 -571510152_01 \n", "66 202 17 None None None None \n", "67 202 18 None None None None \n", "68 206 4 북 남 571542073_01 571511538_02 \n", "69 206 8 남 북 -571511538_02 571542073_02 \n", "70 206 17 None None None None \n", "71 206 18 None None None None \n", "72 210 1 동 남 -571542115_01 571500585_01 \n", "73 210 2 서 동 571500535_02.18 571542115_01 \n", "74 210 3 남 서 571500585_02 571500535_01 \n", "75 210 4 북 남 571511538_02.121 571500585_01 \n", "76 210 5 서 북 571500535_02.18 571511538_01 \n", "77 210 6 동 서 -571542115_01 571500535_01 \n", "78 210 7 북 동 571511538_02.121 571542115_01 \n", "79 210 8 남 북 571500585_02 571511538_01 \n", "80 210 17 None None None None \n", "81 210 18 None None None None \n", "82 210 21 북 서 571511538_02.121 571500535_01 \n", "83 210 21 서 남 571500535_02.18 571500585_01 \n", "84 210 21 남 동 571500585_02 571542115_01 \n", "85 210 21 동 북 -571542115_01 571511538_01 \n", "\n", " node_id \n", "0 i0 \n", "1 i0 \n", "2 i0 \n", "3 i0 \n", "4 i0 \n", "5 i0 \n", "6 i0 \n", "7 i0 \n", "8 i0 \n", "9 i0 \n", "10 i0 \n", "11 i0 \n", "12 i0 \n", "13 i0 \n", "14 i1 \n", "15 i1 \n", "16 i1 \n", "17 i1 \n", "18 i1 \n", "19 i1 \n", "20 i1 \n", "21 i1 \n", "22 i2 \n", "23 i2 \n", "24 i2 \n", "25 i2 \n", "26 i2 \n", "27 i2 \n", "28 i2 \n", "29 i2 \n", "30 i2 \n", "31 i2 \n", "32 i2 \n", "33 i2 \n", "34 i2 \n", "35 i2 \n", "36 i3 \n", "37 i3 \n", "38 i3 \n", "39 i3 \n", "40 i3 \n", "41 i3 \n", "42 i3 \n", "43 i3 \n", "44 i3 \n", "45 i3 \n", "46 i3 \n", "47 i3 \n", "48 i3 \n", "49 i3 \n", "50 i8 \n", "51 i8 \n", "52 i8 \n", "53 i8 \n", "54 i8 \n", "55 i8 \n", "56 i8 \n", "57 i8 \n", "58 i8 \n", "59 i8 \n", "60 i8 \n", "61 i8 \n", "62 i8 \n", "63 i8 \n", "64 i9 \n", "65 i9 \n", "66 i9 \n", "67 i9 \n", "68 i7 \n", "69 i7 \n", "70 i7 \n", "71 i7 \n", "72 i6 \n", "73 i6 \n", "74 i6 \n", "75 i6 \n", "76 i6 \n", "77 i6 \n", "78 i6 \n", "79 i6 \n", "80 i6 \n", "81 i6 \n", "82 i6 \n", "83 i6 \n", "84 i6 \n", "85 i6 " ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# 이동류 매칭\n", "# 각 교차로에 대하여, 가능한 모든 이동류(1~18, 21)에 대한 진입·진출엣지ID를 지정한다.\n", "# 모든 이동류에 대해 지정하므로, 시차제시 이전과 다른 이동류가 등장하더라도 항상 진입·진출 엣지 ID를 지정할 수 있다.\n", "match6 = match5.copy().dropna()\n", "match6 = match6[['inter_no', 'move_no', 'inc_dir', 'out_dir', 'inc_edge', 'out_edge', 'node_id']]\n", "# (1) 가능한 (진입방향, 진출방향) 목록\n", "flows = nema.dropna().apply(lambda row: (row['inc_dir'], row['out_dir']), axis=1).tolist()\n", "# (2) 각 교차로별 방향 목록 : pdires (possible directions)\n", "pdires = {}\n", "for inter_no in match6.inter_no.unique():\n", " dires = match6[match6.inter_no == inter_no][['inc_dir','out_dir']].values.flatten()\n", " dires = {dire for dire in dires if type(dire)==str}\n", " pdires[inter_no] = dires\n", "# (3) 각 (교차로, 진입방향) 별 진입id 목록 : inc2id (incoming direction to incoming edge_id)\n", "inc2id = {}\n", "for inter_no in match6.inter_no.unique():\n", " for inc_dir in pdires[inter_no]:\n", " df = match6[(match6.inter_no==inter_no) & (match6.inc_dir==inc_dir)]\n", " inc2id[(inter_no, inc_dir)] = df.inc_edge.iloc[0]\n", "# (4) 각 (교차로, 진출방향) 별 진출id 목록 : out2id (outgoing direction to outgoing edge_id)\n", "out2id = {}\n", "for inter_no in match6.inter_no.unique():\n", " for out_dir in pdires[inter_no]:\n", " df = match6[(match6.inter_no==inter_no) & (match6.out_dir==out_dir)]\n", " out2id[(inter_no, out_dir)] = df.out_edge.iloc[0]\n", "# (5) 각 교차로별 가능한 (진입방향, 진출방향) 목록 : pflow (possible flows)\n", "pflow = {}\n", "for inter_no in match6.inter_no.unique():\n", " pflow[inter_no] = [flow for flow in flows if set(flow).issubset(pdires[inter_no])]\n", "# (6) 가능한 이동류에 대하여 진입id, 진출id 배정 : matching\n", "inter2node = dict(zip(match6['inter_no'], match6['node_id']))\n", "dires_right = ['북', '서', '남', '동', '북'] # ex (북, 서), (서, 남) 등은 우회전 flow\n", "matching = []\n", "for inter_no in match6.inter_no.unique():\n", " node_id = inter2node[inter_no]\n", " # 좌회전과 직진(1 ~ 16)\n", " for (inc_dir, out_dir) in pflow[inter_no]:\n", " move_no = nema[(nema.inc_dir==inc_dir) & (nema.out_dir==out_dir)].move_no.iloc[0]\n", " inc_edge = inc2id[(inter_no, inc_dir)]\n", " out_edge = out2id[(inter_no, out_dir)]\n", " new_row = pd.DataFrame({'inter_no':[inter_no], 'move_no':[move_no],\n", " 'inc_dir':[inc_dir], 'out_dir':[out_dir],\n", " 'inc_edge':[inc_edge], 'out_edge':[out_edge], 'node_id':[node_id]})\n", " matching.append(new_row)\n", " # 보행신호(17), 전적색(18)\n", " new_row = pd.DataFrame({'inter_no':[inter_no] * 2, 'move_no':[17, 18],\n", " 'inc_dir':[None]*2, 'out_dir':[None]*2,\n", " 'inc_edge':[None]*2, 'out_edge':[None]*2, 'node_id':[node_id]*2})\n", " matching.append(new_row)\n", " # 신호우회전(21)\n", " for d in range(len(dires_right)-1):\n", " inc_dir = dires_right[d]\n", " out_dir = dires_right[d+1]\n", " if {inc_dir, out_dir}.issubset(pdires[inter_no]):\n", " inc_edge = inc2id[(inter_no, inc_dir)]\n", " out_edge = out2id[(inter_no, out_dir)]\n", " new_row = pd.DataFrame({'inter_no':[inter_no], 'move_no':[21],\n", " 'inc_dir':[inc_dir], 'out_dir':[out_dir],\n", " 'inc_edge':[inc_edge], 'out_edge':[out_edge], 'node_id':[node_id]})\n", " matching.append(new_row)\n", "matching = pd.concat(matching)\n", "matching = matching.sort_values(by=['inter_no', 'move_no']).reset_index(drop=True)\n", "with pd.option_context('display.max_rows', None, 'display.max_columns', None):\n", " display(matching)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# B. 5초 간격으로 이동류번호 수집" ] }, { "cell_type": "code", "execution_count": 109, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1704380565\n" ] }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
inter_nophas_Aphas_Bmove_Amove_Bstart_unix
017511841704380560
117611841704380550
217711841704380550
317811841704380540
420122521704380540
520211621704380541
62062217181704380520
7210116181704380550
\n", "
" ], "text/plain": [ " inter_no phas_A phas_B move_A move_B start_unix\n", "0 175 1 1 8 4 1704380560\n", "1 176 1 1 8 4 1704380550\n", "2 177 1 1 8 4 1704380550\n", "3 178 1 1 8 4 1704380540\n", "4 201 2 2 5 2 1704380540\n", "5 202 1 1 6 2 1704380541\n", "6 206 2 2 17 18 1704380520\n", "7 210 1 1 6 18 1704380550" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
inter_nophas_Aphas_Bmove_Amove_Bstart_unix
02062217181704380520
117811841704380540
220122521704380540
320211621704380541
417611841704380550
517711841704380550
6210116181704380550
717511841704380560
\n", "
" ], "text/plain": [ " inter_no phas_A phas_B move_A move_B start_unix\n", "0 206 2 2 17 18 1704380520\n", "1 178 1 1 8 4 1704380540\n", "2 201 2 2 5 2 1704380540\n", "3 202 1 1 6 2 1704380541\n", "4 176 1 1 8 4 1704380550\n", "5 177 1 1 8 4 1704380550\n", "6 210 1 1 6 18 1704380550\n", "7 175 1 1 8 4 1704380560" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "1704380570\n" ] }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
inter_nophas_Aphas_Bmove_Amove_Bstart_unix
017511841704380560
117611841704380550
217711841704380550
317811841704380540
420122521704380540
520211621704380541
62062217181704380520
7210116181704380550
\n", "
" ], "text/plain": [ " inter_no phas_A phas_B move_A move_B start_unix\n", "0 175 1 1 8 4 1704380560\n", "1 176 1 1 8 4 1704380550\n", "2 177 1 1 8 4 1704380550\n", "3 178 1 1 8 4 1704380540\n", "4 201 2 2 5 2 1704380540\n", "5 202 1 1 6 2 1704380541\n", "6 206 2 2 17 18 1704380520\n", "7 210 1 1 6 18 1704380550" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
inter_nophas_Aphas_Bmove_Amove_Bstart_unix
02062217181704380520
117811841704380540
220122521704380540
320211621704380541
417611841704380550
517711841704380550
6210116181704380550
717511841704380560
\n", "
" ], "text/plain": [ " inter_no phas_A phas_B move_A move_B start_unix\n", "0 206 2 2 17 18 1704380520\n", "1 178 1 1 8 4 1704380540\n", "2 201 2 2 5 2 1704380540\n", "3 202 1 1 6 2 1704380541\n", "4 176 1 1 8 4 1704380550\n", "5 177 1 1 8 4 1704380550\n", "6 210 1 1 6 18 1704380550\n", "7 175 1 1 8 4 1704380560" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "1704380575\n" ] }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
inter_nophas_Aphas_Bmove_Amove_Bstart_unix
017511841704380560
117611841704380550
217711841704380550
317811841704380540
420122521704380540
520211621704380541
62062217181704380520
721012621704380550
\n", "
" ], "text/plain": [ " inter_no phas_A phas_B move_A move_B start_unix\n", "0 175 1 1 8 4 1704380560\n", "1 176 1 1 8 4 1704380550\n", "2 177 1 1 8 4 1704380550\n", "3 178 1 1 8 4 1704380540\n", "4 201 2 2 5 2 1704380540\n", "5 202 1 1 6 2 1704380541\n", "6 206 2 2 17 18 1704380520\n", "7 210 1 2 6 2 1704380550" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
inter_nophas_Aphas_Bmove_Amove_Bstart_unix
02062217181704380520
12062217181704380520
217811841704380540
317811841704380540
420122521704380540
520122521704380540
620211621704380541
720211621704380541
817611841704380550
917611841704380550
1017711841704380550
1117711841704380550
12210116181704380550
13210116181704380550
1417511841704380560
1517511841704380560
\n", "
" ], "text/plain": [ " inter_no phas_A phas_B move_A move_B start_unix\n", "0 206 2 2 17 18 1704380520\n", "1 206 2 2 17 18 1704380520\n", "2 178 1 1 8 4 1704380540\n", "3 178 1 1 8 4 1704380540\n", "4 201 2 2 5 2 1704380540\n", "5 201 2 2 5 2 1704380540\n", "6 202 1 1 6 2 1704380541\n", "7 202 1 1 6 2 1704380541\n", "8 176 1 1 8 4 1704380550\n", "9 176 1 1 8 4 1704380550\n", "10 177 1 1 8 4 1704380550\n", "11 177 1 1 8 4 1704380550\n", "12 210 1 1 6 18 1704380550\n", "13 210 1 1 6 18 1704380550\n", "14 175 1 1 8 4 1704380560\n", "15 175 1 1 8 4 1704380560" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "1704380580\n" ] }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
inter_nophas_Aphas_Bmove_Amove_Bstart_unix
017511841704380560
117611841704380550
217711841704380550
317822731704380540
420122521704380540
52022217181704380541
62062217181704380520
721012621704380550
\n", "
" ], "text/plain": [ " inter_no phas_A phas_B move_A move_B start_unix\n", "0 175 1 1 8 4 1704380560\n", "1 176 1 1 8 4 1704380550\n", "2 177 1 1 8 4 1704380550\n", "3 178 2 2 7 3 1704380540\n", "4 201 2 2 5 2 1704380540\n", "5 202 2 2 17 18 1704380541\n", "6 206 2 2 17 18 1704380520\n", "7 210 1 2 6 2 1704380550" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
inter_nophas_Aphas_Bmove_Amove_Bstart_unix
02062217181704380520
12062217181704380520
22062217181704380520
317811841704380540
417811841704380540
517811841704380540
620122521704380540
720122521704380540
820122521704380540
920211621704380541
1020211621704380541
1120211621704380541
1217611841704380550
1317611841704380550
1417611841704380550
1517711841704380550
1617711841704380550
1717711841704380550
18210116181704380550
19210116181704380550
2021012621704380550
2117511841704380560
2217511841704380560
2317511841704380560
\n", "
" ], "text/plain": [ " inter_no phas_A phas_B move_A move_B start_unix\n", "0 206 2 2 17 18 1704380520\n", "1 206 2 2 17 18 1704380520\n", "2 206 2 2 17 18 1704380520\n", "3 178 1 1 8 4 1704380540\n", "4 178 1 1 8 4 1704380540\n", "5 178 1 1 8 4 1704380540\n", "6 201 2 2 5 2 1704380540\n", "7 201 2 2 5 2 1704380540\n", "8 201 2 2 5 2 1704380540\n", "9 202 1 1 6 2 1704380541\n", "10 202 1 1 6 2 1704380541\n", "11 202 1 1 6 2 1704380541\n", "12 176 1 1 8 4 1704380550\n", "13 176 1 1 8 4 1704380550\n", "14 176 1 1 8 4 1704380550\n", "15 177 1 1 8 4 1704380550\n", "16 177 1 1 8 4 1704380550\n", "17 177 1 1 8 4 1704380550\n", "18 210 1 1 6 18 1704380550\n", "19 210 1 1 6 18 1704380550\n", "20 210 1 2 6 2 1704380550\n", "21 175 1 1 8 4 1704380560\n", "22 175 1 1 8 4 1704380560\n", "23 175 1 1 8 4 1704380560" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "del movement\n", "fsec = fsecs[33]\n", "print(fsec)\n", "move = pd.read_csv(f'../../Data/tables/moves/move_{fsec}.csv', index_col=0)\n", "recent_histories = [group.iloc[-1:] for _, group in history[history['end_unix'] < fsec].groupby('inter_no')] # 교차로별로 유닉스시간이 최대인 행들\n", "if not recent_histories:\n", " rhistory = pd.DataFrame({'inter_no':[], 'end_unix':[]}) # recent history\n", "else:\n", " rhistory = pd.concat(recent_histories)\n", "recent_unix = rhistory[['inter_no', 'end_unix']]\n", "move = pd.merge(move, recent_unix, how='left', on='inter_no')\n", "move['end_unix'] = move['end_unix'].fillna(0).astype(int)\n", "move = move.drop_duplicates()\n", "move = move.rename(columns = {'end_unix':'start_unix'})\n", "display(move)\n", "try:\n", " if isinstance(movement, pd.DataFrame): # movement가 존재할 경우 그걸 그대로 씀.\n", " pass\n", " else: \n", " movement = pd.DataFrame()\n", "except NameError: # movement가 존재하지 않는 경우 생성\n", " movement = pd.DataFrame()\n", "movement = pd.concat([movement, move])\n", "movement = movement[movement.start_unix > fsec - 3600]\n", "movement = movement.sort_values(by=['start_unix','inter_no','phas_A','phas_B']).reset_index(drop=True)\n", "display(movement)\n", "\n", "fsec = fsecs[34]\n", "print(fsec)\n", "move = pd.read_csv(f'../../Data/tables/moves/move_{fsec}.csv', index_col=0)\n", "recent_histories = [group.iloc[-1:] for _, group in history[history['end_unix'] < fsec].groupby('inter_no')] # 교차로별로 유닉스시간이 최대인 행들\n", "if not recent_histories:\n", " rhistory = pd.DataFrame({'inter_no':[], 'end_unix':[]}) # recent history\n", "else:\n", " rhistory = pd.concat(recent_histories)\n", "recent_unix = rhistory[['inter_no', 'end_unix']]\n", "move = pd.merge(move, recent_unix, how='left', on='inter_no')\n", "move['end_unix'] = move['end_unix'].fillna(0).astype(int)\n", "move = move.drop_duplicates()\n", "move = move.rename(columns = {'end_unix':'start_unix'})\n", "display(move)\n", "try:\n", " if isinstance(movement, pd.DataFrame): # movement가 존재할 경우 그걸 그대로 씀.\n", " pass\n", " else: \n", " movement = pd.DataFrame()\n", "except NameError: # movement가 존재하지 않는 경우 생성\n", " movement = pd.DataFrame()\n", "display(movement)\n", "movement = pd.concat([movement, move])\n", "movement = movement[movement.start_unix > fsec - 3600]\n", "movement = movement.sort_values(by=['start_unix','inter_no','phas_A','phas_B']).reset_index(drop=True)\n", "\n", "fsec = fsecs[35]\n", "print(fsec)\n", "move = pd.read_csv(f'../../Data/tables/moves/move_{fsec}.csv', index_col=0)\n", "recent_histories = [group.iloc[-1:] for _, group in history[history['end_unix'] < fsec].groupby('inter_no')] # 교차로별로 유닉스시간이 최대인 행들\n", "if not recent_histories:\n", " rhistory = pd.DataFrame({'inter_no':[], 'end_unix':[]}) # recent history\n", "else:\n", " rhistory = pd.concat(recent_histories)\n", "recent_unix = rhistory[['inter_no', 'end_unix']]\n", "move = pd.merge(move, recent_unix, how='left', on='inter_no')\n", "move['end_unix'] = move['end_unix'].fillna(0).astype(int)\n", "move = move.drop_duplicates()\n", "move = move.rename(columns = {'end_unix':'start_unix'})\n", "display(move)\n", "try:\n", " if isinstance(movement, pd.DataFrame): # movement가 존재할 경우 그걸 그대로 씀.\n", " pass\n", " else: \n", " movement = pd.DataFrame()\n", "except NameError: # movement가 존재하지 않는 경우 생성\n", " movement = pd.DataFrame()\n", "display(movement)\n", "movement = pd.concat([movement, move])\n", "movement = movement[movement.start_unix > fsec - 3600]\n", "movement = movement.sort_values(by=['start_unix','inter_no','phas_A','phas_B']).reset_index(drop=True)\n", "\n", "fsec = fsecs[36]\n", "print(fsec)\n", "move = pd.read_csv(f'../../Data/tables/moves/move_{fsec}.csv', index_col=0)\n", "recent_histories = [group.iloc[-1:] for _, group in history[history['end_unix'] < fsec].groupby('inter_no')] # 교차로별로 유닉스시간이 최대인 행들\n", "if not recent_histories:\n", " rhistory = pd.DataFrame({'inter_no':[], 'end_unix':[]}) # recent history\n", "else:\n", " rhistory = pd.concat(recent_histories)\n", "recent_unix = rhistory[['inter_no', 'end_unix']]\n", "move = pd.merge(move, recent_unix, how='left', on='inter_no')\n", "move['end_unix'] = move['end_unix'].fillna(0).astype(int)\n", "move = move.drop_duplicates()\n", "move = move.rename(columns = {'end_unix':'start_unix'})\n", "display(move)\n", "try:\n", " if isinstance(movement, pd.DataFrame): # movement가 존재할 경우 그걸 그대로 씀.\n", " pass\n", " else: \n", " movement = pd.DataFrame()\n", "except NameError: # movement가 존재하지 않는 경우 생성\n", " movement = pd.DataFrame()\n", "display(movement)\n", "movement = pd.concat([movement, move])\n", "movement = movement[movement.start_unix > fsec - 3600]\n", "movement = movement.sort_values(by=['start_unix','inter_no','phas_A','phas_B']).reset_index(drop=True)\n" ] }, { "cell_type": "code", "execution_count": 110, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 17280/17280 [01:37<00:00, 177.77it/s]\n" ] } ], "source": [ "# 5초 단위로 이동류번호 저장 및 신호이력에서 유닉스시각 가져와서 표시, 한시간동안의 데이터만 보관\n", "midnight = int(datetime(2024, 1, 5, 0, 0, 0).timestamp())\n", "next_day = int(datetime(2024, 1, 6, 0, 0, 0).timestamp())\n", "fsecs = range(midnight, next_day, 5) # fsecs : unix time by Five SECondS\n", "fmins = range(midnight, next_day, 300) # fmins : unix time by Five MINuteS\n", "# time2move = dict(zip(fsecs,moves)) # move : 어느 순간의 이동류정보\n", "history = pd.read_csv('../../Data/tables/history.csv', index_col=0)\n", "\n", "time2movement = {} # movement : 어느 순간의, 그 순간으로부터 한시간 동안의 (교차로번호 + 현시별이동류번호 + 시작시간)\n", "# - 아래 절차를 5초마다 반복\n", "for fsec in tqdm(fsecs): # fsec : unix time by Five SECond\n", " # 1. 상태 테이블 조회해서 전체 데이터중 필요데이터(교차로번호, A링 현시번호, A링 이동류번호, B링 현시번호, B링 이동류번호)만 수집 : A\n", " # move = time2move[fsec]\n", " move = pd.read_csv(f'../../Data/tables/moves/move_{fsec}.csv', index_col=0)\n", " # 2. 이력 테이블 조회해서 교차로별로 유닉스시간 최대인 데이터(교차로변호, 종료유닉스타임)만 수집 : B\n", " recent_histories = [group.iloc[-1:] for _, group in history[history['end_unix'] < fsec].groupby('inter_no')] # 교차로별로 유닉스시간이 최대인 행들\n", " if not recent_histories:\n", " rhistory = pd.DataFrame({'inter_no':[], 'end_unix':[]}) # recent history\n", " else:\n", " rhistory = pd.concat(recent_histories)\n", " recent_unix = rhistory[['inter_no', 'end_unix']]\n", " # 3. 상태 테이블 조회정보(A)와 이력 테이블 조회정보(B) 조인(키값 : 교차로번호) : C\n", " move = pd.merge(move, recent_unix, how='left', on='inter_no')\n", " move['end_unix'] = move['end_unix'].fillna(0).astype(int)\n", " move = move.drop_duplicates()\n", " # 4. C데이터 프레임에 신규 컬럼(시작 유닉스타임) 생성 후 종료유닉스 타임 값 입력, 종료 유닉스 타임 컬럼 제거\n", " move = move.rename(columns = {'end_unix':'start_unix'})\n", " # 5. 이동류 이력정보 READ\n", " # - CSV 파일로 서버에 저장된 이동류정보를 읽어옴(파일이 없는 경우에는 데이터가 없는 프레임 D 생성)\n", " try:\n", " if isinstance(movement, pd.DataFrame): # movement가 존재할 경우 그걸 그대로 씀.\n", " pass\n", " else: \n", " movement = pd.DataFrame()\n", " except NameError: # movement가 존재하지 않는 경우 생성\n", " movement = pd.DataFrame()\n", " # 6. 이동류 이력정보 데이터테이블(D)에 C데이터 add\n", " movement = pd.concat([movement, move])\n", " # 7. D데이터 프레임에서 중복데이터 제거(교차로번호, 시작 유닉스타임, A링 현시번호, B링 현시번호 같은 행은 제거)\n", " movement = movement.drop_duplicates(['inter_no','phas_A','phas_B','start_unix'])\n", " # 8. D데이터 보관 시간 기준시간을 시작 유닉스 타임의 최대값 - 3600을 값으로 산출하고, 보관 시간 기준시간보다 작은 시작 유닉스 타임을 가진 행은 모두 제거(1시간 데이터만 보관)\n", " movement = movement[movement.start_unix > fsec - 3600]\n", " movement = movement.sort_values(by=['start_unix','inter_no','phas_A','phas_B']).reset_index(drop=True)\n", "\n", " time2movement[fsec] = movement\n", " movement.to_csv(f'../../Data/tables/movements/movements_{fsec}.csv')\n", "\n", "# 각 movement들의 길이 시각화\n", "import matplotlib.pyplot as plt\n", "plt.plot(fsecs, [len(time2movement[fsec]) for fsec in fsecs])\n", "plt.close()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# C. 5분 간격으로 신호이력 수집 및 통합테이블 생성" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
inter_nostart_hourstart_minuteddur_1ddur_2ddur_3ddur_4ddur_5ddur_6ddur_7ddur_8cycleoffset
017500373925302900016057
117570404229263300017040
217590434533223700018028
31751830464837184100019018
41760037734000000150131
\n", "
" ], "text/plain": [ " inter_no start_hour start_minute ddur_1 ddur_2 ddur_3 ddur_4 ddur_5 \\\n", "0 175 0 0 37 39 25 30 29 \n", "1 175 7 0 40 42 29 26 33 \n", "2 175 9 0 43 45 33 22 37 \n", "3 175 18 30 46 48 37 18 41 \n", "4 176 0 0 37 73 40 0 0 \n", "\n", " ddur_6 ddur_7 ddur_8 cycle offset \n", "0 0 0 0 160 57 \n", "1 0 0 0 170 40 \n", "2 0 0 0 180 28 \n", "3 0 0 0 190 18 \n", "4 0 0 0 150 131 " ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
inter_noend_unixddur_1ddur_2ddur_3ddur_4ddur_5ddur_6ddur_7ddur_8cycleoffset
0206170438052033352626000012010
1178170438054038394023000014050
220117043805402424175817000140133
3202170438054139101000000140103
4176170438055037734000000150131
\n", "
" ], "text/plain": [ " inter_no end_unix ddur_1 ddur_2 ddur_3 ddur_4 ddur_5 ddur_6 \\\n", "0 206 1704380520 33 35 26 26 0 0 \n", "1 178 1704380540 38 39 40 23 0 0 \n", "2 201 1704380540 24 24 17 58 17 0 \n", "3 202 1704380541 39 101 0 0 0 0 \n", "4 176 1704380550 37 73 40 0 0 0 \n", "\n", " ddur_7 ddur_8 cycle offset \n", "0 0 0 120 10 \n", "1 0 0 140 50 \n", "2 0 0 140 133 \n", "3 0 0 140 103 \n", "4 0 0 150 131 " ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "pland = pd.read_csv('../../Data/tables/pland.csv', index_col=0)\n", "plan = pd.read_csv('../../Data/tables/plan.csv', index_col=0)\n", "history = pd.read_csv('../../Data/tables/history.csv', index_col=0)\n", "display(pland.head())\n", "display(history.head())\n", "# plan은 A, B가 통합된 형식으로 history는 분리된 형식으로 표시되었음." ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
start_hourstart_minutestart_seconds
0001704380400
1701704405600
2901704412800
318301704447000
\n", "
" ], "text/plain": [ " start_hour start_minute start_seconds\n", "0 0 0 1704380400\n", "1 7 0 1704405600\n", "2 9 0 1704412800\n", "3 18 30 1704447000" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# split, isplit : A,B 분리 혹은 통합시 사용될 수 있는 딕셔너리\n", "splits = {} # splits maps (inter_no, start_hour, start_minute) to split\n", "for i, row in plan.iterrows():\n", " inter_no = row.inter_no\n", " start_hour = row.start_hour\n", " start_minute = row.start_minute\n", " cycle = row.cycle\n", " cums_A = row[[f'dura_A{j}' for j in range(1,9)]].cumsum()\n", " cums_B = row[[f'dura_B{j}' for j in range(1,9)]].cumsum()\n", " splits[(inter_no, start_hour, start_minute)] = {} # split maps (phas_A, phas_B) to k\n", " k = 0\n", " for t in range(cycle):\n", " new_phas_A = len(cums_A[cums_A < t]) + 1\n", " new_phas_B = len(cums_B[cums_B < t]) + 1\n", " if k == 0 or ((new_phas_A, new_phas_B) != (phas_A, phas_B)):\n", " k += 1\n", " phas_A = new_phas_A\n", " phas_B = new_phas_B\n", " splits[(inter_no, start_hour, start_minute)][(phas_A, phas_B)] = k\n", "\n", "isplits = {} # the inverse of splits\n", "for i in splits:\n", " isplits[i] = {splits[i][k]:k for k in splits[i]} # isplit maps k to (phas_A, phas_B)\n", "\n", "# timetable\n", "timetable = plan[['start_hour', 'start_minute']].drop_duplicates()\n", "timetable['start_seconds'] = midnight + timetable['start_hour'] * 3600 + timetable['start_minute'] * 60\n", "timetable" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2024-01-05 14:29:20\n", "2024-01-05 15:29:19\n" ] } ], "source": [ "# inter_no = 175, m = 30 : 조정 (수축)\n", "# inter_no = 175, m = 70 : 삭제 + 조정(수축)\n", "# inter_no = 175, m = 90 : 결측(전이) + 삭제 + 조정(수축)\n", "# inter_no = 175, m = 140 : 삭제 + 조정(수축)\n", "# inter_no = 176, m = 50 : 조정(수축)\n", "# inter_no = 176, m = 155 : 삭제(마지막 행에서 삭제)\n", "# inter_no = 176, m = 160 : 조정(수축) + 삭제 + 조정(수축)\n", "# inter_no = 176, m = 190 : 결측\n", "# inter_no = 176, m = 220 : 삭제\n", "# inter_no = 176, m = 270 : 삭제\n", "# inter_no = 176, m = 275 : 삭제\n", "# inter_no = 177, m = 40 : 조정(수축)\n", "# inter_no = 178, m = 70 : 삭제\n", "# inter_no = 178, m = 100 : 조정(확장) + 삭제\n", "# inter_no = 178, m = 270 : 결측 + 조정(확장)\n", "\n", "print(datetime.fromtimestamp(1704432560))\n", "print(datetime.fromtimestamp(1704436159))" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "def make_rhistory(m:int):\n", " '''\n", " input : m\n", " - m ranges from 0 to 287, but 0 makes an error where 288 = 86400//300\n", " - present_time = fmins[m] : 현재시점\n", " output : rhistory\n", " - recent history\n", " - 현재시각(present_time) 이전 1시간 동안의 신호이력에 대하여 결측치 및 이상치를 처리한 결과\n", " - 교차로번호(inter_no), 종료유닉스(end_unix), 현시시간(ddur_j), 주기(cycle), 옵셋(offset)\n", " '''\n", " fmins = range(midnight, next_day, 300) # fmins : unix time by Five MINuteS\n", " present_time = fmins[m] # 현재시점\n", " print(datetime.fromtimestamp(present_time))\n", "\n", " Rhists = []\n", " for inter_no in history.inter_no.unique():\n", " # - 5분마다 신호이력 데이터 수집해서 통합테이블 생성할때\n", " # 1. 조회시점의 유닉스 타임을 기준으로 신호이력의 유닉스 타임이 1시간 이내인(Rhist) 데이터 수집\n", " rhistory = history.copy() # recent history (3시간 이내)\n", " rhistory = rhistory[(rhistory.end_unix < present_time) & (rhistory.end_unix >= present_time - 10800)]\n", " hours = np.array(range(midnight, next_day + 1, 3600))\n", " rhist = rhistory.copy()[rhistory.inter_no == inter_no] # 특정한 inter_no\n", " rhist = rhist.reset_index(drop=True)\n", " new_rows = []\n", " # 1-1. 결측치 처리 : 인접한 두 end_unix의 차이가 계획된 주기의 두 배보다 크면 결측이 일어났다고 판단\n", " for n in range(len(rhist) - 1):\n", " curr_unix = rhist.iloc[n].end_unix # current end_unix\n", " next_unix = rhist.iloc[n+1].end_unix # next end_unix\n", " cycle = rhist.iloc[n].cycle\n", " if next_unix - curr_unix >= 2 * cycle:\n", " # 현재 unix를 계획된 주기만큼 늘려가면서 한 행씩 채워나간다.\n", " #(다음 unix와의 차이가 계획된 주기보다 작거나 같아질 때까지)\n", " while next_unix - curr_unix > cycle:\n", " curr_unix += cycle\n", " start_seconds = np.array(timetable.start_seconds)\n", " idx = (start_seconds <= curr_unix).sum() - 1\n", " start_hour = timetable.iloc[idx].start_hour\n", " start_minute = timetable.iloc[idx].start_minute\n", " prow = pland[(pland.inter_no==inter_no) & (pland.start_hour==start_hour) & (pland.start_minute==start_minute)] # planned row\n", " prow = prow.drop(['start_hour', 'start_minute'], axis=1)\n", " prow['end_unix'] = curr_unix\n", " cycle = prow.iloc[0].cycle\n", " new_rows.append(prow)\n", "\n", " rhist = pd.concat([rhist] + new_rows).sort_values(['end_unix'])\n", " rhist = rhist.reset_index(drop=True)\n", "\n", " # 1-2. 이상치 처리 : 기준유닉스로부터의 시간차이와 현시시간합이 11 이상 차이나면 이상치가 발생했다고 판단\n", " Rhist = rhist.copy() # recent history 1704393231\n", " Rhist = Rhist[(Rhist.end_unix < present_time) & (Rhist.end_unix >= present_time - 3600)] # Recent history (1시간 이내)\n", " Rhist = Rhist.reset_index(drop=True)\n", " Rhist['D_n'] = 0\n", " Rhist['S_n'] = 0\n", " for n in range(len(Rhist)):\n", " curr_unix = Rhist.iloc[n].end_unix # current end_unix\n", " cycle = Rhist.iloc[n].cycle\n", " ghour_lt_curr_unix = hours[hours < curr_unix].max() # the greatest hour less than curr_unix\n", " end_unixes = rhist.end_unix.unique()\n", " end_unixes_lt_ghour = np.sort(end_unixes[end_unixes < ghour_lt_curr_unix]) # end unixes less than ghour_lt_end_unix\n", " base_unix = end_unixes_lt_ghour[-5] # 기준유닉스 : curr_unix보다 작은 hour 중에서 가장 큰 값으로부터 다섯 번째로 작은 end_unix\n", " # D_n : 시간차이\n", " D_n = curr_unix - base_unix\n", " ddurations = rhist[(rhist.end_unix > base_unix) & (rhist.end_unix <= curr_unix)][[f'ddur_{j}' for j in range(1,9)]]\n", " # S_n : 현시시간합\n", " S_n = ddurations.values.sum()\n", " Rhist.loc[n, ['D_n', 'S_n']] = [D_n, S_n]\n", " n = 1\n", " while n < len(Rhist):\n", " prev_unix = Rhist[Rhist.index==n-1]['end_unix'].iloc[0] # previous end_unix\n", " curr_unix = Rhist[Rhist.index==n]['end_unix'].iloc[0] # current end_unix\n", " R_n = (curr_unix - prev_unix) / cycle\n", " ghour_lt_curr_unix = hours[hours < curr_unix].max() # the greatest hour less than curr_unix\n", " end_unixes = rhist.end_unix.unique()\n", " end_unixes_lt_ghour = np.sort(end_unixes[end_unixes < ghour_lt_curr_unix]) # end unixes less than ghour_lt_end_unix\n", " base_unix = end_unixes_lt_ghour[-5] # 기준유닉스 : curr_unix보다 작은 hour 중에서 가장 큰 값으로부터 다섯 번째로 작은 end_unix\n", " # D_n : 시간차이\n", " D_n = curr_unix - base_unix\n", " # S_n : 현시시간합\n", " ddurations = rhist[(rhist.end_unix > base_unix) & (rhist.end_unix <= curr_unix)][[f'ddur_{j}' for j in range(1,9)]]\n", " S_n = ddurations.values.sum()\n", " # 비율이 0.5보다 작거나 같으면 해당 행을 삭제\n", " if (abs(D_n - S_n) > 10) & (R_n <= 0.5):\n", " # print(\"lt\", inter_no, curr_unix, round(R_n,2), D_n, S_n)\n", " # display(Rhist.iloc[n])\n", " Rhist = Rhist.drop(index=n)\n", " n += 1\n", " # 행삭제에 따른 curr_unix, D_n, S_n 등 재정의\n", " if not Rhist[Rhist.index==n]['end_unix'].empty: # 마지막 행을 삭제하여 뒤의 행이 없을 때를 대비\n", " curr_unix = Rhist[Rhist.index==n]['end_unix'].iloc[0] # current end_unix\n", " R_n = (curr_unix - prev_unix) / cycle\n", " ghour_lt_curr_unix = hours[hours < curr_unix].max() # the greatest hour less than curr_unix\n", " end_unixes = rhist.end_unix.unique()\n", " end_unixes_lt_ghour = np.sort(end_unixes[end_unixes < ghour_lt_curr_unix]) # end unixes less than ghour_lt_end_unix\n", " base_unix = end_unixes_lt_ghour[-5] # 기준유닉스 : curr_unix보다 작은 hour 중에서 가장 큰 값으로부터 다섯 번째로 작은 end_unix\n", " # D_n : 시간차이\n", " D_n = curr_unix - base_unix\n", " # S_n : 현시시간합\n", " ddurations = rhist[(rhist.end_unix > base_unix) & (rhist.end_unix <= curr_unix)][[f'ddur_{j}' for j in range(1,9)]]\n", " S_n = ddurations.values.sum()\n", " # 비율이 0.5보다 크면 해당 행 조정 (비율을 유지한 채로 현시시간 대체)\n", " if (abs(D_n - S_n) > 10) & (R_n > 0.5):\n", " start_seconds = np.array(timetable.start_seconds)\n", " idx = (start_seconds <= curr_unix).sum() - 1\n", " start_hour = timetable.iloc[idx].start_hour\n", " start_minute = timetable.iloc[idx].start_minute\n", " prow = pland[(pland.inter_no==inter_no) & (pland.start_hour==start_hour) & (pland.start_minute==start_minute)].copy().reset_index(drop=True).iloc[0] # planned row\n", " adjusted_dur = prow[['ddur_1', 'ddur_2', 'ddur_3', 'ddur_4', 'ddur_5', 'ddur_6', 'ddur_7', 'ddur_8']] * R_n\n", " # 조정된 현시시간을 정수로 바꿈\n", " int_parts = adjusted_dur.apply(lambda x: int(x))\n", " frac_parts = adjusted_dur - int_parts\n", " difference = int(round(adjusted_dur.sum())) - int_parts.sum()\n", " # 소수 부분이 가장 큰 상위 'difference'개의 값에 대해 올림 처리\n", " for _ in range(difference):\n", " max_frac_index = frac_parts.idxmax()\n", " int_parts[max_frac_index] += 1\n", " frac_parts[max_frac_index] = 0 # 이미 처리된 항목은 0으로 설정\n", " Rhist.loc[n, ['ddur_1', 'ddur_2', 'ddur_3', 'ddur_4', 'ddur_5', 'ddur_6', 'ddur_7', 'ddur_8']] = int_parts.values\n", " Rhist.loc[n, 'cycle'] = int_parts.sum()\n", " # print(\"gt\", inter_no, curr_unix, round(R_n,2), D_n, S_n)\n", " n += 1\n", " Rhist = Rhist.drop(columns=['offset', 'D_n', 'S_n'])\n", " Rhists.append(Rhist)\n", " Rhists = pd.concat(Rhists)\n", " Rhists = Rhists.sort_values(by=['end_unix', 'inter_no']).reset_index(drop=True)\n", " return Rhists" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "def make_histid(m):\n", " fmins = range(midnight, next_day, 300) # fmins : unix time by Five MINuteS\n", " present_time = fmins[m]\n", " rhistory = make_rhistory(m)\n", " # 2. 시작 유닉스 타임컬럼 생성 후 종류 유닉스 타임에서 현시별 현시기간 컬럼의 합을 뺀 값으로 입력\n", " # - 현시시간의 합을 뺀 시간의 +- 10초 이내에 이전 주기정보가 존재하면 그 유닉스 시간을 시작 유닉스시간 값으로 하고, 존재하지 않으면 현시시간의 합을 뺀 유닉스 시간을 시작 유닉스 시간으로 지정\n", " for i, row in rhistory.iterrows():\n", " # 이전 유닉스 존재하지 않음 => 현시시간 합의 차\n", " # 이전 유닉스 존재, abs < 10 => 이전 유닉스\n", " # 이전 유닉스 존재, abs >=10 => 현시시간 합의 차\n", " inter_no = row.inter_no\n", " end_unix = row.end_unix\n", " elapsed_time = row[[f'ddur_{j}' for j in range(1, 9)]].sum()\n", " start_unix = end_unix - elapsed_time\n", " pre_rows = history[:i] # previous rows\n", " if inter_no in pre_rows.inter_no.unique(): # 이전 유닉스 존재\n", " pre_unix = pre_rows[pre_rows.inter_no == inter_no]['end_unix'].iloc[-1] # previous unix time\n", " if abs(pre_unix - start_unix) < 10: # abs < 10\n", " start_unix = pre_unix\n", " else: # abs >= 10\n", " pass\n", " rhistory.loc[i, 'start_unix'] = start_unix\n", " rhistory[rhistory.isna()] = 0\n", " rhistory['start_unix'] = rhistory['start_unix'].astype(int)\n", " # # with pd.option_context('display.max_rows', None, 'display.max_columns', None):\n", " # # display(rhistory)\n", " rhistory = rhistory[['inter_no', 'start_unix'] + [f'ddur_{j}' for j in range(1, 9)] + ['cycle']]\n", " # 계층화된 형태로 변환\n", " hrhistory = [] # hierarchied recent history\n", " for i, row in rhistory.iterrows():\n", " inter_no = row.inter_no #\n", " start_unix = row.start_unix #\n", " ind = (timetable['start_seconds'] <= row.start_unix).sum() - 1\n", " start_hour = timetable.iloc[ind].start_hour\n", " start_minute = timetable.iloc[ind].start_minute\n", " isplit = isplits[(inter_no, start_hour, start_minute)]\n", " new_rows = []\n", " for j in isplit.keys():\n", " phas_A, phas_B = isplit[j]\n", " duration = row[f'ddur_{j}']\n", " new_rows.append(pd.DataFrame({'inter_no':[inter_no], 'start_unix':[start_unix],\n", " 'phas_A':[phas_A],'phas_B':[phas_B],'duration':[duration]}))\n", " new_rows = pd.concat(new_rows)\n", " hrhistory.append(new_rows)\n", " hrhistory = pd.concat(hrhistory)\n", " hrhistory = hrhistory.sort_values(by = ['start_unix', 'inter_no', 'phas_A', 'phas_B']).reset_index(drop=True)\n", "\n", " # 5초단위로 수집한 이동류정보(time2movement[present_time])와 최근 1시간 신호이력(hrhistory)을 병합\n", " movedur = pd.merge(time2movement[present_time], hrhistory, how='inner', on=['inter_no', 'start_unix', 'phas_A', 'phas_B'])\n", " # movements and durations\n", " movedur = movedur.sort_values(by=['start_unix', 'inter_no', 'phas_A','phas_B'])\n", " movedur = movedur[['inter_no', 'start_unix', 'phas_A', 'phas_B', 'move_A', 'move_B', 'duration']]\n", " # 이동류 매칭 테이블에서 진입id, 진출id를 가져와서 붙임.\n", " for i, row in movedur.iterrows():\n", " inter_no = row.inter_no\n", " start_unix = row.start_unix\n", " move_A = row.move_A\n", " move_B = row.move_B\n", " match_A = matching[(matching.inter_no == inter_no) & (matching.move_no == move_A)].iloc[0]\n", " match_B = matching[(matching.inter_no == inter_no) & (matching.move_no == move_B)].iloc[0]\n", " inc_edge_A = match_A.inc_edge\n", " inc_edge_B = match_B.inc_edge\n", " out_edge_A = match_A.out_edge\n", " out_edge_B = match_B.out_edge\n", " movedur.loc[i, ['inc_edge_A', 'inc_edge_B', 'out_edge_A', 'out_edge_B']] = [inc_edge_A, inc_edge_B, out_edge_A, out_edge_B]\n", " # 이동류 컬럼 제거\n", " # movedur = movedur.drop(['move_A', 'move_B'], axis=1)\n", "\n", " histid = movedur.copy() # history with edge ids (incoming and outgoing edge ids)\n", " return histid" ] } ], "metadata": { "kernelspec": { "display_name": "rts", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.10" } }, "nbformat": 4, "nbformat_minor": 2 }