diff --git a/Analysis/0109_preprocess/0122_preprocess_9.5.ipynb b/Analysis/0109_preprocess/0122_preprocess_9.5.ipynb new file mode 100644 index 000000000..f965c317a --- /dev/null +++ b/Analysis/0109_preprocess/0122_preprocess_9.5.ipynb @@ -0,0 +1,8793 @@ +{ + "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": [ + " 0%| | 0/17280 [00:00\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \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": 6, + "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
01751A8179004-571542797_02571500487_01i0
11751B4003176-571500487_01571542797_02i0
21752A7001095-571500487_01571545870_01i0
31752B3179270-571542797_02571510153_01i0
41753A6090270571545870_02571510153_01i0
51753B1090180571545870_02571542797_02i0
61754A5268000571510153_02571500487_01i0
71754B2270090571510153_02571545870_01i0
81761A8180000-571542810_01-571542797_02.99i1
91761B4359180571542797_02.99571542810_01i1
101762A8180000-571542810_01-571542797_02.99i1
111762B3180270-571542810_01571543469_01i1
121763A5270356571543469_02-571542797_02.99i1
131763B18NaNNaNNaNNaNNaNNaNi1
141771A8180000-571542809_01571542811_01i2
151771B4001176571542811_02571542809_01i2
161772A7000090571542811_02571542107_01i2
171772B3179270-571542809_01571542809_01i2
181773A17NaNNaNNaNNaNNaNNaNi2
191773B18NaNNaNNaNNaNNaNNaNi2
201774A5268000-571542809_01571542811_01i2
211774B1090180571542107_02571542809_01i2
221781A8180000571540304_02571556450_01i3
231781B4000180571556450_02571540304_01i3
241782A7000090571556450_02571500475_01i3
251782B3180270571540304_02571540303_01i3
261783A5270000571540303_02.21571556450_01i3
271783B2270090571540303_02.21571500475_01i3
281784A6090270-571500475_01571540303_01i3
291784B1090180-571500475_01571540304_01i3
302011A8180000-571500569_01571500583_02i8
312011B3180270-571500569_01571500618_01i8
322012A5270000571500618_02571500583_02i8
332012B2270090571500618_02571500617_01i8
342013A6090270571500617_02571500618_01i8
352013B2270090571500618_02571500617_01i8
362014A6090270571500617_02571500618_01i8
372014B1090180571500617_02571500569_01i8
382015A7000090571500583_01571500617_01i8
392015B4000180571500583_01571500569_01i8
402021A6090270571510152_02-571510152_01i9
412021B2270090571510152_01571510152_01.65i9
422022A17NaNNaNNaNNaNNaNNaNi9
432022B18NaNNaNNaNNaNNaNNaNi9
442061A8180000-571511538_02571542073_02i7
452061B4000180571542073_01571511538_02i7
462062A17NaNNaNNaNNaNNaNNaNi7
472062B18NaNNaNNaNNaNNaNNaNi7
482063A8180000-571511538_02571542073_02i7
492063B4000180571542073_01571511538_02i7
502064A17NaNNaNNaNNaNNaNNaNi7
512064B18NaNNaNNaNNaNNaNNaNi7
522101A6090270-571542115_01571500535_01i6
532101B18NaNNaNNaNNaNNaNNaNi6
542102A5268000571500535_02.18571511538_01i6
552102B2270090571500535_02.18571542115_01i6
562103A7359090571511538_02.121571542115_01i6
572103B4000180571511538_02.121571500585_01i6
582104A8180000571500585_02571511538_01i6
592104B3180270571500585_02571500535_01i6
\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 \n", + "\n", + " inc_edge out_edge node_id \n", + "0 -571542797_02 571500487_01 i0 \n", + "1 -571500487_01 571542797_02 i0 \n", + "2 -571500487_01 571545870_01 i0 \n", + "3 -571542797_02 571510153_01 i0 \n", + "4 571545870_02 571510153_01 i0 \n", + "5 571545870_02 571542797_02 i0 \n", + "6 571510153_02 571500487_01 i0 \n", + "7 571510153_02 571545870_01 i0 \n", + "8 -571542810_01 -571542797_02.99 i1 \n", + "9 571542797_02.99 571542810_01 i1 \n", + "10 -571542810_01 -571542797_02.99 i1 \n", + "11 -571542810_01 571543469_01 i1 \n", + "12 571543469_02 -571542797_02.99 i1 \n", + "13 NaN NaN i1 \n", + "14 -571542809_01 571542811_01 i2 \n", + "15 571542811_02 571542809_01 i2 \n", + "16 571542811_02 571542107_01 i2 \n", + "17 -571542809_01 571542809_01 i2 \n", + "18 NaN NaN i2 \n", + "19 NaN NaN i2 \n", + "20 -571542809_01 571542811_01 i2 \n", + "21 571542107_02 571542809_01 i2 \n", + "22 571540304_02 571556450_01 i3 \n", + "23 571556450_02 571540304_01 i3 \n", + "24 571556450_02 571500475_01 i3 \n", + "25 571540304_02 571540303_01 i3 \n", + "26 571540303_02.21 571556450_01 i3 \n", + "27 571540303_02.21 571500475_01 i3 \n", + "28 -571500475_01 571540303_01 i3 \n", + "29 -571500475_01 571540304_01 i3 \n", + "30 -571500569_01 571500583_02 i8 \n", + "31 -571500569_01 571500618_01 i8 \n", + "32 571500618_02 571500583_02 i8 \n", + "33 571500618_02 571500617_01 i8 \n", + "34 571500617_02 571500618_01 i8 \n", + "35 571500618_02 571500617_01 i8 \n", + "36 571500617_02 571500618_01 i8 \n", + "37 571500617_02 571500569_01 i8 \n", + "38 571500583_01 571500617_01 i8 \n", + "39 571500583_01 571500569_01 i8 \n", + "40 571510152_02 -571510152_01 i9 \n", + "41 571510152_01 571510152_01.65 i9 \n", + "42 NaN NaN i9 \n", + "43 NaN NaN i9 \n", + "44 -571511538_02 571542073_02 i7 \n", + "45 571542073_01 571511538_02 i7 \n", + "46 NaN NaN i7 \n", + "47 NaN NaN i7 \n", + "48 -571511538_02 571542073_02 i7 \n", + "49 571542073_01 571511538_02 i7 \n", + "50 NaN NaN i7 \n", + "51 NaN NaN i7 \n", + "52 -571542115_01 571500535_01 i6 \n", + "53 NaN NaN i6 \n", + "54 571500535_02.18 571511538_01 i6 \n", + "55 571500535_02.18 571542115_01 i6 \n", + "56 571511538_02.121 571542115_01 i6 \n", + "57 571511538_02.121 571500585_01 i6 \n", + "58 571500585_02 571511538_01 i6 \n", + "59 571500585_02 571500535_01 i6 " + ] + }, + "execution_count": 6, + "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.sort_values(by=['inter_no','phase_no','ring_type']).reset_index(drop=True)\n", + "match5" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array(['u00', 'u20', 'u30', 'u31', 'u32', 'u60'], dtype=object)" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# 유턴/연동교차로에 대하여 진입ID, 진출ID 부여\n", + "node2inter = dict(zip(inter_node['node_id'], inter_node['inter_no']))\n", + "\n", + "uturn = pd.read_csv('../../Data/tables/child_uturn.csv')\n", + "coord = pd.read_csv('../../Data/tables/child_coord.csv')\n", + "\n", + "child_ids = inter_node[inter_node.inter_type=='child'].node_id.unique()\n", + "ch2pa = {} # child to parent\n", + "for child_id in child_ids:\n", + " parent_no = inter_node[inter_node.node_id==child_id].inter_no.iloc[0]\n", + " sub_inter_node = inter_node[inter_node.inter_no==parent_no]\n", + " ch2pa[child_id] = sub_inter_node[sub_inter_node.inter_type=='parent'].iloc[0].node_id\n", + "directions = ['북', '북동', '동', '남동', '남', '남서', '서', '북서'] # 정북기준 시계방향으로 8방향\n", + "u_ids = uturn.child_id.unique()\n", + "u_ids" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "u00 i0 좌회전시 북\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \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
01751A8179004NaNNaNu00
11751B4003176NaNNaNu00
21752A19001095571500487_02571500487_01.32u00
31752B3179270NaNNaNu00
41753A6090270NaNNaNu00
51753B1090180NaNNaNu00
61754A5268000NaNNaNu00
71754B2270090NaNNaNu00
\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 19 북 동 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", + "\n", + " inc_edge out_edge node_id \n", + "0 NaN NaN u00 \n", + "1 NaN NaN u00 \n", + "2 571500487_02 571500487_01.32 u00 \n", + "3 NaN NaN u00 \n", + "4 NaN NaN u00 \n", + "5 NaN NaN u00 \n", + "6 NaN NaN u00 \n", + "7 NaN NaN u00 " + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "u20 i2 보행신호시 북\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \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
01771A8180000NaNNaNu20
11771B4001176NaNNaNu20
21772A7000090NaNNaNu20
31772B3179270NaNNaNu20
41773A17NaNNaNNaNNaN571542810_01.51571542810_02u20
51773B18NaNNaNNaNNaNNaNNaNu20
61774A5268000NaNNaNu20
71774B1090180NaNNaNu20
\n", + "
" + ], + "text/plain": [ + " inter_no phase_no ring_type move_no inc_dir out_dir inc_angle out_angle \\\n", + "0 177 1 A 8 남 북 180 000 \n", + "1 177 1 B 4 북 남 001 176 \n", + "2 177 2 A 7 북 동 000 090 \n", + "3 177 2 B 3 남 서 179 270 \n", + "4 177 3 A 17 NaN NaN NaN NaN \n", + "5 177 3 B 18 NaN NaN NaN NaN \n", + "6 177 4 A 5 서 북 268 000 \n", + "7 177 4 B 1 동 남 090 180 \n", + "\n", + " inc_edge out_edge node_id \n", + "0 NaN NaN u20 \n", + "1 NaN NaN u20 \n", + "2 NaN NaN u20 \n", + "3 NaN NaN u20 \n", + "4 571542810_01.51 571542810_02 u20 \n", + "5 NaN NaN u20 \n", + "6 NaN NaN u20 \n", + "7 NaN NaN u20 " + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "u30 i3 보행신호시 북\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \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
01781A8180000NaNNaNu30
11781B4000180NaNNaNu30
21782A7000090NaNNaNu30
31782B3180270NaNNaNu30
41783A5270000NaNNaNu30
51783B2270090NaNNaNu30
61784A19090270571556452_01571556452_02u30
71784B1090180NaNNaNu30
\n", + "
" + ], + "text/plain": [ + " inter_no phase_no ring_type move_no inc_dir out_dir inc_angle out_angle \\\n", + "0 178 1 A 8 남 북 180 000 \n", + "1 178 1 B 4 북 남 000 180 \n", + "2 178 2 A 7 북 동 000 090 \n", + "3 178 2 B 3 남 서 180 270 \n", + "4 178 3 A 5 서 북 270 000 \n", + "5 178 3 B 2 서 동 270 090 \n", + "6 178 4 A 19 동 서 090 270 \n", + "7 178 4 B 1 동 남 090 180 \n", + "\n", + " inc_edge out_edge node_id \n", + "0 NaN NaN u30 \n", + "1 NaN NaN u30 \n", + "2 NaN NaN u30 \n", + "3 NaN NaN u30 \n", + "4 NaN NaN u30 \n", + "5 NaN NaN u30 \n", + "6 571556452_01 571556452_02 u30 \n", + "7 NaN NaN u30 " + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "u31 i3 보행신호시 동\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \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
01781A19180000571500475_02571500475_01.26u31
11781B4000180NaNNaNu31
21782A7000090NaNNaNu31
31782B3180270NaNNaNu31
41783A5270000NaNNaNu31
51783B2270090NaNNaNu31
61784A6090270NaNNaNu31
71784B1090180NaNNaNu31
\n", + "
" + ], + "text/plain": [ + " inter_no phase_no ring_type move_no inc_dir out_dir inc_angle out_angle \\\n", + "0 178 1 A 19 남 북 180 000 \n", + "1 178 1 B 4 북 남 000 180 \n", + "2 178 2 A 7 북 동 000 090 \n", + "3 178 2 B 3 남 서 180 270 \n", + "4 178 3 A 5 서 북 270 000 \n", + "5 178 3 B 2 서 동 270 090 \n", + "6 178 4 A 6 동 서 090 270 \n", + "7 178 4 B 1 동 남 090 180 \n", + "\n", + " inc_edge out_edge node_id \n", + "0 571500475_02 571500475_01.26 u31 \n", + "1 NaN NaN u31 \n", + "2 NaN NaN u31 \n", + "3 NaN NaN u31 \n", + "4 NaN NaN u31 \n", + "5 NaN NaN u31 \n", + "6 NaN NaN u31 \n", + "7 NaN NaN u31 " + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "u32 i3 보행신호시 서\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \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
01781A8180000NaNNaNu32
11781B19000180571540303_02-571540303_02u32
21782A7000090NaNNaNu32
31782B3180270NaNNaNu32
41783A5270000NaNNaNu32
51783B2270090NaNNaNu32
61784A6090270NaNNaNu32
71784B1090180NaNNaNu32
\n", + "
" + ], + "text/plain": [ + " inter_no phase_no ring_type move_no inc_dir out_dir inc_angle out_angle \\\n", + "0 178 1 A 8 남 북 180 000 \n", + "1 178 1 B 19 북 남 000 180 \n", + "2 178 2 A 7 북 동 000 090 \n", + "3 178 2 B 3 남 서 180 270 \n", + "4 178 3 A 5 서 북 270 000 \n", + "5 178 3 B 2 서 동 270 090 \n", + "6 178 4 A 6 동 서 090 270 \n", + "7 178 4 B 1 동 남 090 180 \n", + "\n", + " inc_edge out_edge node_id \n", + "0 NaN NaN u32 \n", + "1 571540303_02 -571540303_02 u32 \n", + "2 NaN NaN u32 \n", + "3 NaN NaN u32 \n", + "4 NaN NaN u32 \n", + "5 NaN NaN u32 \n", + "6 NaN NaN u32 \n", + "7 NaN NaN u32 " + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "u60 i6 직좌시 서\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \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
02101A6090270NaNNaNu60
12101B18NaNNaNNaNNaNNaNNaNu60
22102A19268000571500535_02-571500535_02u60
32102B19270090571500535_02-571500535_02u60
42103A7359090NaNNaNu60
52103B4000180NaNNaNu60
62104A8180000NaNNaNu60
72104B3180270NaNNaNu60
\n", + "
" + ], + "text/plain": [ + " inter_no phase_no ring_type move_no inc_dir out_dir inc_angle out_angle \\\n", + "0 210 1 A 6 동 서 090 270 \n", + "1 210 1 B 18 NaN NaN NaN NaN \n", + "2 210 2 A 19 서 북 268 000 \n", + "3 210 2 B 19 서 동 270 090 \n", + "4 210 3 A 7 북 동 359 090 \n", + "5 210 3 B 4 북 남 000 180 \n", + "6 210 4 A 8 남 북 180 000 \n", + "7 210 4 B 3 남 서 180 270 \n", + "\n", + " inc_edge out_edge node_id \n", + "0 NaN NaN u60 \n", + "1 NaN NaN u60 \n", + "2 571500535_02 -571500535_02 u60 \n", + "3 571500535_02 -571500535_02 u60 \n", + "4 NaN NaN u60 \n", + "5 NaN NaN u60 \n", + "6 NaN NaN u60 \n", + "7 NaN NaN u60 " + ] + }, + "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", + "
inter_nophase_noring_typemove_noinc_dirout_dirinc_angleout_angleinc_edgeout_edgenode_id
01781A20NaNNaNNaNNaNNaNNaNc30
11781B20NaNNaNNaNNaNNaNNaNc30
21782A20NaNNaNNaNNaN571542116_01-571542116_02.96c30
31782B20NaNNaNNaNNaN571542116_02.96571542116_02.164c30
41783A20NaNNaNNaNNaN571542116_01-571542116_02.96c30
51783B20NaNNaNNaNNaN571542116_02.96571542116_02.164c30
61784A20NaNNaNNaNNaN571542116_01-571542116_02.96c30
71784B20NaNNaNNaNNaN571542116_02.96571542116_02.164c30
\n", + "
" + ], + "text/plain": [ + " inter_no phase_no ring_type move_no inc_dir out_dir inc_angle \\\n", + "0 178 1 A 20 NaN NaN NaN \n", + "1 178 1 B 20 NaN NaN NaN \n", + "2 178 2 A 20 NaN NaN NaN \n", + "3 178 2 B 20 NaN NaN NaN \n", + "4 178 3 A 20 NaN NaN NaN \n", + "5 178 3 B 20 NaN NaN NaN \n", + "6 178 4 A 20 NaN NaN NaN \n", + "7 178 4 B 20 NaN NaN NaN \n", + "\n", + " out_angle inc_edge out_edge node_id \n", + "0 NaN NaN NaN c30 \n", + "1 NaN NaN NaN c30 \n", + "2 NaN 571542116_01 -571542116_02.96 c30 \n", + "3 NaN 571542116_02.96 571542116_02.164 c30 \n", + "4 NaN 571542116_01 -571542116_02.96 c30 \n", + "5 NaN 571542116_02.96 571542116_02.164 c30 \n", + "6 NaN 571542116_01 -571542116_02.96 c30 \n", + "7 NaN 571542116_02.96 571542116_02.164 c30 " + ] + }, + "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", + "
inter_nophase_noring_typemove_noinc_dirout_dirinc_angleout_angleinc_edgeout_edgenode_id
01751A8179004-571542797_02571500487_01i0
11751B4003176-571500487_01571542797_02i0
21752A7001095-571500487_01571545870_01i0
31752B3179270-571542797_02571510153_01i0
41753A6090270571545870_02571510153_01i0
....................................
32102B19270090571500535_02-571500535_02u60
42103A7359090NaNNaNu60
52103B4000180NaNNaNu60
62104A8180000NaNNaNu60
72104B3180270NaNNaNu60
\n", + "

116 rows × 11 columns

\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", + ".. ... ... ... ... ... ... ... ... \n", + "3 210 2 B 19 서 동 270 090 \n", + "4 210 3 A 7 북 동 359 090 \n", + "5 210 3 B 4 북 남 000 180 \n", + "6 210 4 A 8 남 북 180 000 \n", + "7 210 4 B 3 남 서 180 270 \n", + "\n", + " inc_edge out_edge node_id \n", + "0 -571542797_02 571500487_01 i0 \n", + "1 -571500487_01 571542797_02 i0 \n", + "2 -571500487_01 571545870_01 i0 \n", + "3 -571542797_02 571510153_01 i0 \n", + "4 571545870_02 571510153_01 i0 \n", + ".. ... ... ... \n", + "3 571500535_02 -571500535_02 u60 \n", + "4 NaN NaN u60 \n", + "5 NaN NaN u60 \n", + "6 NaN NaN u60 \n", + "7 NaN NaN u60 \n", + "\n", + "[116 rows x 11 columns]" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# 유턴/연동교차로에 대하여 진입ID, 진출ID 부여\n", + "node2inter = dict(zip(inter_node['node_id'], inter_node['inter_no']))\n", + "\n", + "uturn = pd.read_csv('../../Data/tables/child_uturn.csv')\n", + "coord = pd.read_csv('../../Data/tables/child_coord.csv')\n", + "child_ids = inter_node[inter_node.inter_type=='child'].node_id.unique()\n", + "ch2pa = {} # child to parent\n", + "for child_id in child_ids:\n", + " parent_no = inter_node[inter_node.node_id==child_id].inter_no.iloc[0]\n", + " sub_inter_node = inter_node[inter_node.inter_no==parent_no]\n", + " ch2pa[child_id] = sub_inter_node[sub_inter_node.inter_type=='parent'].iloc[0].node_id\n", + "directions = ['북', '북동', '동', '남동', '남', '남서', '서', '북서'] # 정북기준 시계방향으로 8방향\n", + "u_ids = uturn.child_id.unique()\n", + "# 각 child uturn node에 대하여 (inc_edge_id, out_edge_id) 부여\n", + "cmatches = []\n", + "for _, row in uturn.iterrows():\n", + " child_id = row.child_id\n", + " parent_id = row.parent_id\n", + " direction = row.direction\n", + " condition = row.condition\n", + " inc_edge_id = row.inc_edge\n", + " out_edge_id = row.out_edge\n", + " ind = directions.index(direction)\n", + " if condition == \"좌회전시\":\n", + " print(child_id, parent_id, condition, direction)\n", + " inc_dire = direction\n", + " out_dire_A = out_dire_B = directions[(ind + 2) % len(directions)]\n", + " elif condition == \"직진시\":\n", + " print(child_id, parent_id, condition, direction)\n", + " inc_dire = direction\n", + " out_dire_A = out_dire_B = directions[(ind + 4) % len(directions)]\n", + " elif condition == \"직좌시\":\n", + " print(child_id, parent_id, condition, direction)\n", + " inc_dire = direction\n", + " out_dire_A = directions[(ind + 2) % len(directions)]\n", + " out_dire_B = directions[(ind + 4) % len(directions)]\n", + " elif condition == \"보행신호시\":\n", + " print(child_id, parent_id, condition, direction)\n", + " inc_dire = directions[(ind + 2) % len(directions)]\n", + " out_dire_A = directions[(ind - 2) % len(directions)]\n", + " out_dire_B = directions[(ind - 2) % len(directions)]\n", + " cmatch = match5.copy()[match5.node_id==parent_id] # match dataframe for a child node\n", + " cmatch = cmatch.sort_values(by=['phase_no', 'ring_type']).reset_index(drop=True)\n", + " cmatch['node_id'] = child_id\n", + " cmatch[['inc_edge', 'out_edge']] = np.nan\n", + " if condition == '직좌시':\n", + " ap = cmatch[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_A)].phase_no.iloc[0]\n", + " bp = cmatch[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_B)].phase_no.iloc[0]\n", + " # 직진과 좌회전이 같은 현시에 있는 경우에만 (inc_edge_id, out_edge_id)를 부여한다.\n", + " if ap == bp:\n", + " cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_A), ['inc_edge', 'out_edge']] = [inc_edge_id, out_edge_id]\n", + " cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_B), ['inc_edge', 'out_edge']] = [inc_edge_id, out_edge_id]\n", + " elif condition == '보행신호시':\n", + " cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_A), ['inc_edge', 'out_edge']] = [inc_edge_id, out_edge_id]\n", + " cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_B), ['inc_edge', 'out_edge']] = [inc_edge_id, out_edge_id]\n", + " # 이동류번호가 17(보행신호)이면서 유턴노드방향으로 가는 신호가 없으면 (inc_edge_id, out_edge_id)를 부여한다.\n", + " cmatch.loc[(cmatch.move_no==17) & (cmatch.out_dir!=direction), ['inc_edge', 'out_edge']] = [inc_edge_id, out_edge_id]\n", + " else:\n", + " cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_A), ['inc_edge', 'out_edge']] = [inc_edge_id, out_edge_id]\n", + " cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_B), ['inc_edge', 'out_edge']] = [inc_edge_id, out_edge_id]\n", + " # 유턴신호의 이동류번호를 19로 부여한다.\n", + " cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_A), 'move_no'] = 19\n", + " cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_B), 'move_no'] = 19\n", + " display(cmatch)\n", + " cmatches.append(cmatch)\n", + "\n", + "# 각 child coordination node에 대하여 (inc_edge_id, out_edge_id) 부여\n", + "coord['inter_no'] = coord['parent_id'].map(node2inter)\n", + "coord = coord.rename(columns={'child_id':'node_id'})\n", + "coord[['inc_dir', 'out_dir', 'inc_angle','out_angle']] = np.nan\n", + "coord['move_no'] = 20\n", + "coord = coord[['inter_no', 'phase_no', 'ring_type', 'move_no', 'inc_dir', 'out_dir', 'inc_angle','out_angle', 'inc_edge', 'out_edge', 'node_id']]\n", + "# display(coord)\n", + "cmatches = pd.concat(cmatches)\n", + "display(coord)\n", + "match6 = pd.concat([match5, cmatches, coord]).drop_duplicates().sort_values(by=['inter_no', 'node_id', 'phase_no', 'ring_type'])\n", + "# with pd.option_context('display.max_rows', None, 'display.max_columns', None):\n", + "match6.to_csv('../../Data/tables/matching/match6.csv')\n", + "display(match6)" + ] + }, + { + "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", + " \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
........................
692108571500585_02571511538_01i6
7021021571511538_02.121571500535_01i6
7121021571500535_02.18571500585_01i6
7221021571500585_02571542115_01i6
7321021-571542115_01571511538_01i6
\n", + "

74 rows × 7 columns

\n", + "
" + ], + "text/plain": [ + " inter_no move_no inc_dir out_dir inc_edge out_edge node_id\n", + "0 175 1 동 남 571545870_02 571542797_02 i0\n", + "1 175 2 서 동 571510153_02 571545870_01 i0\n", + "2 175 3 남 서 -571542797_02 571510153_01 i0\n", + "3 175 4 북 남 -571500487_01 571542797_02 i0\n", + "4 175 5 서 북 571510153_02 571500487_01 i0\n", + ".. ... ... ... ... ... ... ...\n", + "69 210 8 남 북 571500585_02 571511538_01 i6\n", + "70 210 21 북 서 571511538_02.121 571500535_01 i6\n", + "71 210 21 서 남 571500535_02.18 571500585_01 i6\n", + "72 210 21 남 동 571500585_02 571542115_01 i6\n", + "73 210 21 동 북 -571542115_01 571511538_01 i6\n", + "\n", + "[74 rows x 7 columns]" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# 이동류 매칭\n", + "# 각 교차로에 대하여, 가능한 모든 이동류(1~18, 21)에 대한 진입·진출엣지ID를 지정한다.\n", + "# 모든 이동류에 대해 지정하므로, 시차제시 이전과 다른 이동류가 등장하더라도 항상 진입·진출 엣지 ID를 지정할 수 있다.\n", + "match7 = match6.copy()\n", + "match7 = match7[['inter_no', 'move_no', 'inc_dir', 'out_dir', 'inc_edge', 'out_edge', 'node_id']]\n", + "\n", + "parent_ids = sorted(inter_node[inter_node.inter_type=='parent'].node_id.unique())\n", + "child_ids = sorted(inter_node[inter_node.inter_type=='child'].node_id.unique())\n", + "\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 node_id in parent_ids:\n", + " dires = match7[match7.node_id == node_id][['inc_dir','out_dir']].values.flatten()\n", + " dires = {dire for dire in dires if type(dire)==str}\n", + " pdires[node_id] = dires\n", + "# (3) 각 (교차로, 진입방향) 별 진입id 목록 : inc2id (incoming direction to incoming edge_id)\n", + "inc2id = {}\n", + "for node_id in parent_ids:\n", + " for inc_dir in pdires[node_id]:\n", + " df = match7[(match7.node_id==node_id) & (match7.inc_dir==inc_dir)]\n", + " inc2id[(node_id, inc_dir)] = df.inc_edge.iloc[0]\n", + "# (4) 각 (교차로, 진출방향) 별 진출id 목록 : out2id (outgoing direction to outgoing edge_id)\n", + "out2id = {}\n", + "for node_id in parent_ids:\n", + " for out_dir in pdires[node_id]:\n", + " df = match7[(match7.node_id==node_id) & (match7.out_dir==out_dir)]\n", + " out2id[(node_id, out_dir)] = df.out_edge.iloc[0]\n", + "# (5) 각 교차로별 가능한 (진입방향, 진출방향) 목록 : pflow (possible flows)\n", + "pflow = {}\n", + "for node_id in parent_ids:\n", + " pflow[node_id] = [flow for flow in flows if set(flow).issubset(pdires[node_id])]\n", + "# (6) 가능한 이동류에 대하여 진입id, 진출id 배정 : matching\n", + "node2inter = dict(zip(match7['node_id'], match7['inter_no']))\n", + "dires_right = ['북', '서', '남', '동', '북'] # ex (북, 서), (서, 남) 등은 우회전 flow\n", + "matching = []\n", + "for node_id in parent_ids:\n", + " inter_no = node2inter[node_id]\n", + " # 좌회전과 직진(1 ~ 16)\n", + " for (inc_dir, out_dir) in pflow[node_id]:\n", + " move_no = nema[(nema.inc_dir==inc_dir) & (nema.out_dir==out_dir)].move_no.iloc[0]\n", + " inc_edge = inc2id[(node_id, inc_dir)]\n", + " out_edge = out2id[(node_id, 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[node_id]):\n", + " inc_edge = inc2id[(node_id, inc_dir)]\n", + " out_edge = out2id[(node_id, 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.append(match7[match7.node_id.isin(child_ids)])\n", + "matching = pd.concat(matching)\n", + "matching = matching.dropna().sort_values(by=['inter_no', 'node_id', 'move_no']).reset_index(drop=True)\n", + "matching['move_no'] = matching['move_no'].astype(int)\n", + "matching.to_csv('../../Data/tables/matching/matching.csv')\n", + "display(matching)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# B. 5초 간격으로 이동류번호 수집" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + " 0%| | 0/17280 [00:00 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": 11, + "metadata": {}, + "outputs": [], + "source": [ + "plan = pd.read_csv('../../Data/tables/plan.csv', index_col=0)\n", + "history = pd.read_csv('../../Data/tables/history.csv', index_col=0)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "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": 12, + "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": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2024-01-05 03:20:00\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \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_unixdura_A1dura_A2dura_A3dura_A4dura_A5dura_A6dura_A7dura_A8dura_B1dura_B2dura_B3dura_B4dura_B5dura_B6dura_B7dura_B8cycle
601781704388800383940230000383940230000140
60201170438880024241758170002424175817000140
6020217043888003910100000039101000000140
702061704388800333526260000333526260000120
561771704388801362068260000362068260000150
............................................................
782101704392159432956220000244856220000150
841781704392160383940230000383940230000140
84201170439216024241758170002424175817000140
982061704392160333526260000333526260000120
8420217043922113910100000039101000000140
\n", + "

194 rows × 19 columns

\n", + "
" + ], + "text/plain": [ + " inter_no start_unix dura_A1 dura_A2 dura_A3 dura_A4 dura_A5 \\\n", + "60 178 1704388800 38 39 40 23 0 \n", + "60 201 1704388800 24 24 17 58 17 \n", + "60 202 1704388800 39 101 0 0 0 \n", + "70 206 1704388800 33 35 26 26 0 \n", + "56 177 1704388801 36 20 68 26 0 \n", + ".. ... ... ... ... ... ... ... \n", + "78 210 1704392159 43 29 56 22 0 \n", + "84 178 1704392160 38 39 40 23 0 \n", + "84 201 1704392160 24 24 17 58 17 \n", + "98 206 1704392160 33 35 26 26 0 \n", + "84 202 1704392211 39 101 0 0 0 \n", + "\n", + " dura_A6 dura_A7 dura_A8 dura_B1 dura_B2 dura_B3 dura_B4 dura_B5 \\\n", + "60 0 0 0 38 39 40 23 0 \n", + "60 0 0 0 24 24 17 58 17 \n", + "60 0 0 0 39 101 0 0 0 \n", + "70 0 0 0 33 35 26 26 0 \n", + "56 0 0 0 36 20 68 26 0 \n", + ".. ... ... ... ... ... ... ... ... \n", + "78 0 0 0 24 48 56 22 0 \n", + "84 0 0 0 38 39 40 23 0 \n", + "84 0 0 0 24 24 17 58 17 \n", + "98 0 0 0 33 35 26 26 0 \n", + "84 0 0 0 39 101 0 0 0 \n", + "\n", + " dura_B6 dura_B7 dura_B8 cycle \n", + "60 0 0 0 140 \n", + "60 0 0 0 140 \n", + "60 0 0 0 140 \n", + "70 0 0 0 120 \n", + "56 0 0 0 150 \n", + ".. ... ... ... ... \n", + "78 0 0 0 150 \n", + "84 0 0 0 140 \n", + "84 0 0 0 140 \n", + "98 0 0 0 120 \n", + "84 0 0 0 140 \n", + "\n", + "[194 rows x 19 columns]" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "m = 40\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", + "# 1. 조회시점의 유닉스 타임 이전의 신호이력 수집\n", + "rhistory = history.copy() # recent history\n", + "rhistory = rhistory[(rhistory.end_unix < present_time)]\n", + "# 2. 시작 유닉스 타임컬럼 생성 후 종류 유닉스 타임에서 현시별 현시기간 컬럼의 합을 뺀 값으로 입력\n", + "# - 현시시간의 합을 뺀 시간의 +- 10초 이내에 이전 주기정보가 존재하면 그 유닉스 시간을 시작 유닉스시간 값으로 하고, 존재하지 않으면 현시시간의 합을 뺀 유닉스 시간을 시작 유닉스 시간으로 지정\n", + "for i, row in rhistory.iterrows():\n", + " inter_no = row.inter_no\n", + " end_unix = row.end_unix\n", + " elapsed_time = row[[f'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]].sum() // 2 # 현시시간 합\n", + " # 이전 유닉스 존재하지 않음 : 현시시간 합의 차\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", + " # 이전 유닉스 존재, abs < 10 : 이전 유닉스\n", + " if abs(pre_unix - start_unix) < 10:\n", + " start_unix = pre_unix\n", + " # 이전 유닉스 존재, abs >=10 : 현시시간 합의 차\n", + " else:\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", + "rhistory[['inter_no', 'start_unix', 'cycle']][rhistory.inter_no==175]\n", + "rhistory = rhistory[['inter_no', 'start_unix'] + [f'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)] + ['cycle']]\n", + "rhistory\n", + "\n", + "# 2-1. 참값 판단 프로세스\n", + "hours = np.array(range(midnight, next_day + 1, 3600)) # 정각에 해당하는 시각들 목록\n", + "\n", + "def calculate_DS(rhist, curr_unix):\n", + " ghour_lt_curr_unix = hours[hours <= curr_unix].max() # the greatest hour less than (or equal to) curr_unix\n", + " start_unixes = rhist.start_unix.unique()\n", + " start_unixes_lt_ghour = np.sort(start_unixes[start_unixes < ghour_lt_curr_unix]) # start unixes less than ghour_lt_curr_unix\n", + " # 기준유닉스(base_unix) : curr_unix보다 작은 hour 중에서 가장 큰 값으로부터 다섯 번째로 작은 start_unix\n", + " if list(start_unixes_lt_ghour):\n", + " base_unix = start_unixes_lt_ghour[-5]\n", + " # start_unixes_lt_ghour가 비었을 경우에는 맨 앞 start_unix로 base_unix를 지정\n", + " else:\n", + " base_unix = rhist.start_unix.min()\n", + " D_n = curr_unix - base_unix\n", + " S_n_durs = rhist[(rhist.start_unix > base_unix) & (rhist.start_unix <= curr_unix)] \\\n", + " [[f'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]]\n", + " S_n = S_n_durs.values.sum() // 2\n", + " return D_n, S_n\n", + "\n", + "rhists = []\n", + "for inter_no in sorted(rhistory.inter_no.unique()):\n", + " rhist = rhistory.copy()[rhistory.inter_no==inter_no]\n", + " rhist = rhist.drop_duplicates(subset=['start_unix']).reset_index(drop=True)\n", + "\n", + " # D_n 및 S_n 값 정의\n", + " rhist['D_n'] = 0 # D_n : 시간차이\n", + " rhist['S_n'] = 0 # S_n : 현시시간합\n", + " for n in range(len(rhist)):\n", + " curr_unix = rhist.iloc[n].start_unix # current start_unix\n", + " rhist.loc[n, ['D_n', 'S_n']] = calculate_DS(rhist, curr_unix)\n", + "\n", + " # 이전시각, 현재시각\n", + " prev_unix = rhist.loc[0, 'start_unix'] # previous start_unix\n", + " curr_unix = rhist.loc[1, 'start_unix'] # current start_unix\n", + "\n", + " # rhist의 마지막 행에 도달할 때까지 반복\n", + " while True:\n", + " n = rhist[rhist.start_unix==curr_unix].index[0]\n", + " cycle = rhist.loc[n, 'cycle']\n", + " D_n = rhist.loc[n, 'D_n']\n", + " S_n = rhist.loc[n, 'S_n']\n", + " # 참값인 경우\n", + " if (abs(D_n - S_n) <= 5):\n", + " pass\n", + " # 참값이 아닌 경우\n", + " else:\n", + " # 2-1-1. 결측치 처리 : 인접한 두 start_unix의 차이가 계획된 주기의 두 배보다 크면 결측이 일어났다고 판단, 신호계획의 현시시간으로 \"대체\"\n", + " if curr_unix - prev_unix >= 2 * cycle:\n", + " # prev_unix를 계획된 주기만큼 늘려가면서 한 행씩 채워나간다.\n", + " # (curr_unix와의 차이가 계획된 주기보다 작거나 같아질 때까지)\n", + " new_rows = []\n", + " while curr_unix - prev_unix > cycle:\n", + " prev_unix += cycle\n", + " # 신호 계획(prow) 불러오기\n", + " start_seconds = np.array(timetable.start_seconds)\n", + " idx = (start_seconds <= prev_unix).sum() - 1\n", + " start_hour = timetable.iloc[idx].start_hour\n", + " start_minute = timetable.iloc[idx].start_minute\n", + " prow = plan.copy()[(plan.inter_no==inter_no) & (plan.start_hour==start_hour) & (plan.start_minute==start_minute)] # planned row\n", + " # prow에서 필요한 부분을 rhist에 추가\n", + " prow['start_unix'] = prev_unix\n", + " prow = prow.drop(['start_hour', 'start_minute', 'offset'], axis=1)\n", + " cycle = prow.iloc[0].cycle\n", + " rhist = pd.concat([rhist, prow])\n", + " rhist = rhist.sort_values(by='start_unix').reset_index(drop=True)\n", + " n += 1\n", + "\n", + " # 2-1-2. 이상치 처리 : 비율에 따라 해당 행을 \"삭제\"(R_n <= 0.5) 또는 \"조정\"(R_n > 0.5)한다\n", + " R_n = (curr_unix - prev_unix) / cycle # R_n : 비율\n", + " # R_n이 0.5보다 작거나 같으면 해당 행을 삭제\n", + " if R_n <= 0.5:\n", + " rhist = rhist.drop(index=n).reset_index(drop=True)\n", + " # 행삭제에 따른 curr_unix, R_n 재정의\n", + " curr_unix = rhist.loc[n, 'start_unix']\n", + " R_n = (curr_unix - prev_unix) / cycle # R_n : 비율\n", + "\n", + " # R_n이 0.5보다 크면 해당 행 조정 (비율을 유지한 채로 현시시간 대체)\n", + " if R_n > 0.5:\n", + " # 신호 계획(prow) 불러오기\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 = plan[(plan.inter_no==inter_no) & (plan.start_hour==start_hour) & (plan.start_minute==start_minute)] # planned row\n", + " # 조정된 현시시간 (prow에 R_n을 곱하고 정수로 바꿈)\n", + " adjusted_dur = prow.copy()[[f'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]] * R_n\n", + " int_parts = adjusted_dur.iloc[0].apply(lambda x: int(x))\n", + " frac_parts = adjusted_dur.iloc[0] - int_parts\n", + " difference = round(adjusted_dur.iloc[0].sum()) - int_parts.sum()\n", + " for _ in range(difference): # 소수 부분이 가장 큰 상위 '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에 조정된 현시시간을 반영\n", + " rhist.loc[n, [f'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]] = int_parts.values\n", + " rhist.loc[n, 'cycle'] = int_parts.sum().sum() // 2\n", + "\n", + " if n == rhist.index[-1]:\n", + " break\n", + " prev_unix = curr_unix\n", + " curr_unix = rhist.loc[n+1, 'start_unix']\n", + " # rhist['start_dt'] = rhist['start_unix'].map(lambda x:datetime.fromtimestamp(x))\n", + "\n", + " # 생략해도 무방할 코드\n", + " rhist = rhist.reset_index(drop=True)\n", + " rhist = rhist.sort_values(by=['start_unix'])\n", + "\n", + " # D_n 및 S_n 값 재정의\n", + " for n in range(len(rhist)):\n", + " curr_unix = rhist.iloc[n].start_unix # current start_unix\n", + " rhist.loc[n, ['D_n', 'S_n']] = calculate_DS(rhist, curr_unix)\n", + " rhists.append(rhist)\n", + "rhists = pd.concat(rhists).sort_values(by=['start_unix','inter_no'])\n", + "rhists = rhists[rhists.start_unix >= present_time - 3600]\n", + "rhists = rhists.drop(columns=['D_n', 'S_n'])\n", + "rhists" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + " 0%| | 0/17280 [00:00\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \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
81751184
151752273
201753361
241753462
261754452
\n", + "" + ], + "text/plain": [ + " inter_no phas_A phas_B move_A move_B\n", + "8 175 1 1 8 4\n", + "15 175 2 2 7 3\n", + "20 175 3 3 6 1\n", + "24 175 3 4 6 2\n", + "26 175 4 4 5 2" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "movements_wo_start_unix_list = [] # movements without start_unix\n", + "for inter_no in sorted(movements.inter_no.unique()):\n", + " movements_wo_start_unix = movements[movements_wo_start_unix.inter_no==inter_no]\n", + " movements_wo_start_unix = movements_wo_start_unix[['inter_no', 'phas_A', 'phas_B', 'move_A', 'move_B']]\n", + " movements_wo_start_unix = movements_wo_start_unix.drop_duplicates().sort_values(by=['phas_A','phas_B'])\n", + " movements_wo_start_unix_list.append(movements_wo_start_unix)\n", + "movements_wo_start_unix = pd.concat(movements_wo_start_unix_list)\n", + "movements_wo_start_unix.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 67, + "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_unixphas_Aphas_Bduration
017817043888001138
117817043888002239
217817043888003340
317817043888004423
420117043888001124
..................
76720617043921602235
76820617043921603326
76920617043921604426
77020217043922111139
771202170439221122101
\n", + "

772 rows × 5 columns

\n", + "
" + ], + "text/plain": [ + " inter_no start_unix phas_A phas_B duration\n", + "0 178 1704388800 1 1 38\n", + "1 178 1704388800 2 2 39\n", + "2 178 1704388800 3 3 40\n", + "3 178 1704388800 4 4 23\n", + "4 201 1704388800 1 1 24\n", + ".. ... ... ... ... ...\n", + "767 206 1704392160 2 2 35\n", + "768 206 1704392160 3 3 26\n", + "769 206 1704392160 4 4 26\n", + "770 202 1704392211 1 1 39\n", + "771 202 1704392211 2 2 101\n", + "\n", + "[772 rows x 5 columns]" + ] + }, + "execution_count": 67, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# 계층화된 형태로 변환\n", + "hrhists = [] # hierarchied recent history\n", + "for i, row in rhists.iterrows():\n", + " inter_no = row.inter_no\n", + " start_unix = row.start_unix\n", + "\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", + " phas_As = [isplit[j][0] for j in isplit.keys()]\n", + " phas_Bs = [isplit[j][1] for j in isplit.keys()]\n", + " durs_A = row[[f'dura_A{j}' for j in range(1,9)]]\n", + " durs_B = row[[f'dura_B{j}' for j in range(1,9)]]\n", + " durations = []\n", + " for j in range(1, len(isplit)+1):\n", + " ja = isplit[j][0]\n", + " jb = isplit[j][1]\n", + " if ja == jb:\n", + " durations.append(min(durs_A[ja-1], durs_B[jb-1]))\n", + " else:\n", + " durations.append(abs(durs_A[ja-1] - durs_B[ja-1]))\n", + " new_rows = pd.DataFrame({'inter_no':[inter_no] * len(durations), 'start_unix':[start_unix] * len(durations),\n", + " 'phas_A':phas_As, 'phas_B':phas_Bs, 'duration':durations})\n", + " hrhists.append(new_rows)\n", + "hrhists = pd.concat(hrhists)\n", + "hrhists = hrhists.sort_values(by = ['start_unix', 'inter_no', 'phas_A', 'phas_B']).reset_index(drop=True)\n", + "hrhists" + ] + }, + { + "cell_type": "code", + "execution_count": 133, + "metadata": {}, + "outputs": [], + "source": [ + "movement = time2movement[present_time]" + ] + }, + { + "cell_type": "code", + "execution_count": 138, + "metadata": {}, + "outputs": [], + "source": [ + "# 중복을 제거하고 (inter_no, start_unix) 쌍을 만듭니다.\n", + "hrhists_inter_unix = set(hrhists[['inter_no', 'start_unix']].drop_duplicates().itertuples(index=False, name=None))\n", + "movement_inter_unix = set(movement[['inter_no', 'start_unix']].drop_duplicates().itertuples(index=False, name=None))\n", + "\n", + "# hrhists에는 있지만 movement에는 없는 (inter_no, start_unix) 쌍을 찾습니다.\n", + "missing_in_movement = hrhists_inter_unix - movement_inter_unix\n", + "\n", + "# 새로운 행들을 생성합니다.\n", + "new_rows = []\n", + "for inter_no, start_unix in missing_in_movement:\n", + " # movements_wo_start_unix에서 해당 inter_no의 데이터를 찾습니다.\n", + " new_row = movements_wo_start_unix[movements_wo_start_unix['inter_no'] == inter_no].copy()\n", + " # start_unix 값을 설정합니다.\n", + " new_row['start_unix'] = start_unix\n", + " new_rows.append(new_row)\n", + "\n", + "# 새로운 데이터프레임을 생성하고 기존 movement 데이터프레임과 합칩니다.\n", + "new_movement = pd.concat(new_rows, ignore_index=True)\n", + "movement_updated = pd.concat([movement, new_movement], ignore_index=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 143, + "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", + "
inter_nonode_idstart_unixphas_Aphas_Bdurationinc_edge_Aout_edge_Ainc_edge_Bout_edge_B
0177i217043888011136-571542809_01571542811_01571542811_02571542809_01
1177i217043888012220571542811_02571542107_01-571542809_01571542809_01
2177i217043888013368NaNNaNNaNNaN
3177i217043888014426-571542809_01571542811_01571542107_02571542809_01
4176i117043888501137-571542810_01-571542797_02.99571542797_02.99571542810_01
.................................
748206i717043921602235NaNNaNNaNNaN
749206i717043921603326-571511538_02571542073_02571542073_01571511538_02
750206i717043921604426NaNNaNNaNNaN
751202i917043922111139571510152_02-571510152_01571510152_01571510152_01.65
752202i9170439221122101NaNNaNNaNNaN
\n", + "

757 rows × 10 columns

\n", + "
" + ], + "text/plain": [ + " inter_no node_id start_unix phas_A phas_B duration inc_edge_A \\\n", + "0 177 i2 1704388801 1 1 36 -571542809_01 \n", + "1 177 i2 1704388801 2 2 20 571542811_02 \n", + "2 177 i2 1704388801 3 3 68 NaN \n", + "3 177 i2 1704388801 4 4 26 -571542809_01 \n", + "4 176 i1 1704388850 1 1 37 -571542810_01 \n", + ".. ... ... ... ... ... ... ... \n", + "748 206 i7 1704392160 2 2 35 NaN \n", + "749 206 i7 1704392160 3 3 26 -571511538_02 \n", + "750 206 i7 1704392160 4 4 26 NaN \n", + "751 202 i9 1704392211 1 1 39 571510152_02 \n", + "752 202 i9 1704392211 2 2 101 NaN \n", + "\n", + " out_edge_A inc_edge_B out_edge_B \n", + "0 571542811_01 571542811_02 571542809_01 \n", + "1 571542107_01 -571542809_01 571542809_01 \n", + "2 NaN NaN NaN \n", + "3 571542811_01 571542107_02 571542809_01 \n", + "4 -571542797_02.99 571542797_02.99 571542810_01 \n", + ".. ... ... ... \n", + "748 NaN NaN NaN \n", + "749 571542073_02 571542073_01 571511538_02 \n", + "750 NaN NaN NaN \n", + "751 -571510152_01 571510152_01 571510152_01.65 \n", + "752 NaN NaN NaN \n", + "\n", + "[757 rows x 10 columns]" + ] + }, + "execution_count": 143, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "movedur = pd.merge(movement_updated, hrhists, how='inner', on=['inter_no', 'start_unix', 'phas_A', 'phas_B']) # 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", + "\n", + "# 이동류 매칭 테이블에서 진입id, 진출id를 가져와서 붙임.\n", + "for i, row in movedur.iterrows():\n", + " inter_no = row.inter_no\n", + " start_unix = row.start_unix\n", + " # incoming and outgoing edges A\n", + " move_A = row.move_A\n", + " if move_A in [17, 18]:\n", + " inc_edge_A = np.nan\n", + " out_edge_A = np.nan\n", + " else:\n", + " match_A = matching[(matching.inter_no == inter_no) & (matching.move_no == move_A)].iloc[0]\n", + " inc_edge_A = match_A.inc_edge\n", + " out_edge_A = match_A.out_edge\n", + " movedur.loc[i, ['inc_edge_A', 'out_edge_A']] = [inc_edge_A, out_edge_A]\n", + " # incoming and outgoing edges B\n", + " move_B = row.move_B\n", + " if move_B in [17, 18]:\n", + " inc_edge_B = np.nan\n", + " out_edge_B = np.nan\n", + " else:\n", + " match_B = matching[(matching.inter_no == inter_no) & (matching.move_no == move_B)].iloc[0]\n", + " inc_edge_B = match_B.inc_edge\n", + " out_edge_B = match_B.out_edge\n", + " movedur.loc[i, ['inc_edge_B', 'out_edge_B']] = [inc_edge_B, out_edge_B]\n", + "\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", + "histid['node_id'] = histid['inter_no'].map(inter2node)\n", + "histid = histid[['inter_no', 'node_id', 'start_unix', 'phas_A', 'phas_B', 'duration', 'inc_edge_A', 'out_edge_A', 'inc_edge_B', 'out_edge_B']]\n", + "histid = histid[histid.start_unix > present_time - 3600]\n", + "histid" + ] + }, + { + "cell_type": "code", + "execution_count": 71, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2024-01-05 16:40:00\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \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_nonode_idstart_unixphas_Aphas_Bdurationinc_edge_Aout_edge_Ainc_edge_Bout_edge_B
0202i917044368101146571510152_02-571510152_01571510152_01571510152_01.65
1202i9170443681022114NaNNaNNaNNaN
2178i317044368601138571540304_02571556450_01571556450_02571540304_01
3178i317044368602239571556450_02571500475_01571540304_02571540303_01
4178i317044368603343571540303_02.21571556450_01571540303_02.21571500475_01
.................................
477202i9170444017122114NaNNaNNaNNaN
478206i717044401711145-571511538_02571542073_02571542073_01571511538_02
479206i717044401712253NaNNaNNaNNaN
480206i717044401713326-571511538_02571542073_02571542073_01571511538_02
481206i717044401714426NaNNaNNaNNaN
\n", + "

482 rows × 10 columns

\n", + "
" + ], + "text/plain": [ + " inter_no node_id start_unix phas_A phas_B duration inc_edge_A \\\n", + "0 202 i9 1704436810 1 1 46 571510152_02 \n", + "1 202 i9 1704436810 2 2 114 NaN \n", + "2 178 i3 1704436860 1 1 38 571540304_02 \n", + "3 178 i3 1704436860 2 2 39 571556450_02 \n", + "4 178 i3 1704436860 3 3 43 571540303_02.21 \n", + ".. ... ... ... ... ... ... ... \n", + "477 202 i9 1704440171 2 2 114 NaN \n", + "478 206 i7 1704440171 1 1 45 -571511538_02 \n", + "479 206 i7 1704440171 2 2 53 NaN \n", + "480 206 i7 1704440171 3 3 26 -571511538_02 \n", + "481 206 i7 1704440171 4 4 26 NaN \n", + "\n", + " out_edge_A inc_edge_B out_edge_B \n", + "0 -571510152_01 571510152_01 571510152_01.65 \n", + "1 NaN NaN NaN \n", + "2 571556450_01 571556450_02 571540304_01 \n", + "3 571500475_01 571540304_02 571540303_01 \n", + "4 571556450_01 571540303_02.21 571500475_01 \n", + ".. ... ... ... \n", + "477 NaN NaN NaN \n", + "478 571542073_02 571542073_01 571511538_02 \n", + "479 NaN NaN NaN \n", + "480 571542073_02 571542073_01 571511538_02 \n", + "481 NaN NaN NaN \n", + "\n", + "[482 rows x 10 columns]" + ] + }, + "execution_count": 71, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "m = 200\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", + "# (구) make_rhistory\n", + "Rhists = [] # Recent history (1시간 이내)\n", + "for inter_no in history.inter_no.unique():\n", + " # - 5분마다 신호이력 데이터 수집해서 통합테이블 생성할때\n", + " # 1. 조회시점의 유닉스 타임 이전의 신호이력 수집\n", + " rhistory = history.copy() # recent history\n", + " rhistory = rhistory[(rhistory.end_unix < present_time)]\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 = plan[(plan.inter_no==inter_no) & (plan.start_hour==start_hour) & (plan.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", + " 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 - 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'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]]\n", + " # S_n : 현시시간합\n", + " S_n = ddurations.values.sum() // 2\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'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]]\n", + " S_n = ddurations.values.sum() // 2\n", + " # 비율이 0.5보다 작거나 같으면 해당 행을 삭제\n", + " if (abs(D_n - S_n) > 10) & (R_n <= 0.5):\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'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]]\n", + " S_n = ddurations.values.sum() // 2\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 = plan[(plan.inter_no==inter_no) & (plan.start_hour==start_hour) & (plan.start_minute==start_minute)].copy().reset_index(drop=True).iloc[0] # planned row\n", + " adjusted_dur = prow[[f'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]] * 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, [f'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]] = int_parts.values\n", + " Rhist.loc[n, 'cycle'] = int_parts.sum() // 2\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", + "\n", + "# (구) make_histid\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'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]].sum() // 2 # 현시시간 합\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", + "rhistory = rhistory[['inter_no', 'start_unix'] + [f'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)] + ['cycle']]\n", + "\n", + "# 계층화된 형태로 변환\n", + "hrhistory = [] # hierarchized recent history\n", + "for i, row in rhistory.iterrows():\n", + " inter_no = row.inter_no\n", + " start_unix = row.start_unix\n", + "\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", + " phas_As = [isplit[j][0] for j in isplit.keys()]\n", + " phas_Bs = [isplit[j][1] for j in isplit.keys()]\n", + " durs_A = row[[f'dura_A{j}' for j in range(1,9)]]\n", + " durs_B = row[[f'dura_B{j}' for j in range(1,9)]]\n", + " durations = []\n", + " for j in range(1, len(isplit)+1):\n", + " ja = isplit[j][0]\n", + " jb = isplit[j][1]\n", + " if ja == jb:\n", + " durations.append(min(durs_A[ja-1], durs_B[jb-1]))\n", + " else:\n", + " durations.append(abs(durs_A[ja-1] - durs_B[ja-1]))\n", + " new_rows = pd.DataFrame({'inter_no':[inter_no] * len(durations), 'start_unix':[start_unix] * len(durations),\n", + " 'phas_A':phas_As, 'phas_B':phas_Bs, 'duration':durations})\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']) # 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", + "\n", + "# 이동류 매칭 테이블에서 진입id, 진출id를 가져와서 붙임.\n", + "for i, row in movedur.iterrows():\n", + " inter_no = row.inter_no\n", + " start_unix = row.start_unix\n", + " # incoming and outgoing edges A\n", + " move_A = row.move_A\n", + " if move_A in [17, 18]:\n", + " inc_edge_A = np.nan\n", + " out_edge_A = np.nan\n", + " else:\n", + " match_A = matching[(matching.inter_no == inter_no) & (matching.move_no == move_A)].iloc[0]\n", + " inc_edge_A = match_A.inc_edge\n", + " out_edge_A = match_A.out_edge\n", + " movedur.loc[i, ['inc_edge_A', 'out_edge_A']] = [inc_edge_A, out_edge_A]\n", + " # incoming and outgoing edges B\n", + " move_B = row.move_B\n", + " if move_B in [17, 18]:\n", + " inc_edge_B = np.nan\n", + " out_edge_B = np.nan\n", + " else:\n", + " match_B = matching[(matching.inter_no == inter_no) & (matching.move_no == move_B)].iloc[0]\n", + " inc_edge_B = match_B.inc_edge\n", + " out_edge_B = match_B.out_edge\n", + " movedur.loc[i, ['inc_edge_B', 'out_edge_B']] = [inc_edge_B, out_edge_B]\n", + "\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", + "histid['node_id'] = histid['inter_no'].map(inter2node)\n", + "histid = histid[['inter_no', 'node_id', 'start_unix', 'phas_A', 'phas_B', 'duration', 'inc_edge_A', 'out_edge_A', 'inc_edge_B', 'out_edge_B']]\n", + "histid = histid[histid.start_unix > present_time - 3600]\n", + "# 시뮬레이션 시작시각 : 현재시각 - 600\n", + "# 시뮬레이션 종료시각 : 현재시각 - 300\n", + "# 현재시각 : present_time, PT\n", + "# PT-900 ... PT-600 ... PT-300 ... PT\n", + "histid" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2024-01-05 04:10:00\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \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_nonode_idstart_unixphas_Aphas_Bdurationinc_edge_Aout_edge_Ainc_edge_Bout_edge_B
0176i117043918501137-571542810_01-571542797_02.99571542797_02.99571542810_01
1176i117043918502273-571542810_01-571542797_02.99-571542810_01571543469_01
2176i117043918503340571543469_02-571542797_02.99NaNNaN
3178i317043918801138571540304_02571556450_01571556450_02571540304_01
4178i317043918802239571556450_02571500475_01571540304_02571540303_01
.................................
528201i817043952501124-571500569_01571500583_02-571500569_01571500618_01
529201i817043952502224571500618_02571500583_02571500618_02571500617_01
530201i817043952503317571500617_02571500618_01571500618_02571500617_01
531201i817043952504458571500617_02571500618_01571500617_02571500569_01
532201i817043952505517571500583_01571500617_01571500583_01571500569_01
\n", + "

533 rows × 10 columns

\n", + "
" + ], + "text/plain": [ + " inter_no node_id start_unix phas_A phas_B duration inc_edge_A \\\n", + "0 176 i1 1704391850 1 1 37 -571542810_01 \n", + "1 176 i1 1704391850 2 2 73 -571542810_01 \n", + "2 176 i1 1704391850 3 3 40 571543469_02 \n", + "3 178 i3 1704391880 1 1 38 571540304_02 \n", + "4 178 i3 1704391880 2 2 39 571556450_02 \n", + ".. ... ... ... ... ... ... ... \n", + "528 201 i8 1704395250 1 1 24 -571500569_01 \n", + "529 201 i8 1704395250 2 2 24 571500618_02 \n", + "530 201 i8 1704395250 3 3 17 571500617_02 \n", + "531 201 i8 1704395250 4 4 58 571500617_02 \n", + "532 201 i8 1704395250 5 5 17 571500583_01 \n", + "\n", + " out_edge_A inc_edge_B out_edge_B \n", + "0 -571542797_02.99 571542797_02.99 571542810_01 \n", + "1 -571542797_02.99 -571542810_01 571543469_01 \n", + "2 -571542797_02.99 NaN NaN \n", + "3 571556450_01 571556450_02 571540304_01 \n", + "4 571500475_01 571540304_02 571540303_01 \n", + ".. ... ... ... \n", + "528 571500583_02 -571500569_01 571500618_01 \n", + "529 571500583_02 571500618_02 571500617_01 \n", + "530 571500618_01 571500618_02 571500617_01 \n", + "531 571500618_01 571500617_02 571500569_01 \n", + "532 571500617_01 571500583_01 571500569_01 \n", + "\n", + "[533 rows x 10 columns]" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "make_histid(50)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "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", + "
inter_noend_unixdura_A1dura_A2dura_A3dura_A4dura_A5dura_A6dura_A7dura_A8...dura_B3dura_B4dura_B5dura_B6dura_B7dura_B8cycleoffsetD_nS_n
0202170438054039101000000...00000014010300
1202170438068039101000000...00000014010300
2202170438082039101000000...00000014010300
3202170438096039101000000...00000014010300
4202170438110039101000000...00000014010300
..................................................................
200202170440967946114000000...00000016010300
201202170440984046114000000...00000016010300
202202170441000046114000000...00000016010300
203202170441016046114000000...00000016010300
204202170441032046114000000...00000016010300
\n", + "

205 rows × 22 columns

\n", + "
" + ], + "text/plain": [ + " inter_no end_unix dura_A1 dura_A2 dura_A3 dura_A4 dura_A5 \\\n", + "0 202 1704380540 39 101 0 0 0 \n", + "1 202 1704380680 39 101 0 0 0 \n", + "2 202 1704380820 39 101 0 0 0 \n", + "3 202 1704380960 39 101 0 0 0 \n", + "4 202 1704381100 39 101 0 0 0 \n", + ".. ... ... ... ... ... ... ... \n", + "200 202 1704409679 46 114 0 0 0 \n", + "201 202 1704409840 46 114 0 0 0 \n", + "202 202 1704410000 46 114 0 0 0 \n", + "203 202 1704410160 46 114 0 0 0 \n", + "204 202 1704410320 46 114 0 0 0 \n", + "\n", + " dura_A6 dura_A7 dura_A8 ... dura_B3 dura_B4 dura_B5 dura_B6 \\\n", + "0 0 0 0 ... 0 0 0 0 \n", + "1 0 0 0 ... 0 0 0 0 \n", + "2 0 0 0 ... 0 0 0 0 \n", + "3 0 0 0 ... 0 0 0 0 \n", + "4 0 0 0 ... 0 0 0 0 \n", + ".. ... ... ... ... ... ... ... ... \n", + "200 0 0 0 ... 0 0 0 0 \n", + "201 0 0 0 ... 0 0 0 0 \n", + "202 0 0 0 ... 0 0 0 0 \n", + "203 0 0 0 ... 0 0 0 0 \n", + "204 0 0 0 ... 0 0 0 0 \n", + "\n", + " dura_B7 dura_B8 cycle offset D_n S_n \n", + "0 0 0 140 103 0 0 \n", + "1 0 0 140 103 0 0 \n", + "2 0 0 140 103 0 0 \n", + "3 0 0 140 103 0 0 \n", + "4 0 0 140 103 0 0 \n", + ".. ... ... ... ... ... ... \n", + "200 0 0 160 103 0 0 \n", + "201 0 0 160 103 0 0 \n", + "202 0 0 160 103 0 0 \n", + "203 0 0 160 103 0 0 \n", + "204 0 0 160 103 0 0 \n", + "\n", + "[205 rows x 22 columns]" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "m = 100\n", + "fmins = range(midnight, next_day, 300) # fmins : unix time by Five MINuteS\n", + "present_time = fmins[m] # 현재시점\n", + "\n", + "# 1. 신호이력 데이터 수집\n", + "rhistory = history.copy()[(history.end_unix < present_time)]\n", + "rhistory = rhistory.reset_index(drop=True)\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", + "rhist['D_n'] = 0 # D_n : 시간차이\n", + "rhist['S_n'] = 0 # S_n : 현시시간합\n", + "rhist" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2024-01-05 08:19:00\n", + "2024-01-05 07:20:20\n" + ] + } + ], + "source": [ + "movement = time2movement[present_time]\n", + "max_unix = movement.start_unix.max()\n", + "min_unix = movement.start_unix.min()\n", + "print(datetime.fromtimestamp(max_unix))\n", + "print(datetime.fromtimestamp(min_unix))" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "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", + "
inter_nophas_Aphas_Bmove_Amove_Bstart_unix
020111831704406820
120122521704406820
220133621704406820
320144611704406820
420155741704406820
.....................
59820211621704410320
5992022217181704410320
60020111831704410340
60120122521704410340
60220155741704410340
\n", + "

603 rows × 6 columns

\n", + "
" + ], + "text/plain": [ + " inter_no phas_A phas_B move_A move_B start_unix\n", + "0 201 1 1 8 3 1704406820\n", + "1 201 2 2 5 2 1704406820\n", + "2 201 3 3 6 2 1704406820\n", + "3 201 4 4 6 1 1704406820\n", + "4 201 5 5 7 4 1704406820\n", + ".. ... ... ... ... ... ...\n", + "598 202 1 1 6 2 1704410320\n", + "599 202 2 2 17 18 1704410320\n", + "600 201 1 1 8 3 1704410340\n", + "601 201 2 2 5 2 1704410340\n", + "602 201 5 5 7 4 1704410340\n", + "\n", + "[603 rows x 6 columns]" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "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 = [] # Recent history (1시간 이내)\n", + "for inter_no in history.inter_no.unique():\n", + " # - 5분마다 신호이력 데이터 수집해서 통합테이블 생성할때\n", + " # 1. 조회시점의 유닉스 타임을 기준으로 신호이력의 유닉스 타임이 1시간 이내인(Rhist) 데이터 수집\n", + " rhistory = history.copy() # recent history\n", + " rhistory = rhistory[(rhistory.end_unix < present_time)]\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 = plan[(plan.inter_no==inter_no) & (plan.start_hour==start_hour) & (plan.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", + " 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 - 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'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]]\n", + " # S_n : 현시시간합\n", + " S_n = ddurations.values.sum() // 2\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'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]]\n", + " S_n = ddurations.values.sum() // 2\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'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]]\n", + " S_n = ddurations.values.sum() // 2\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 = plan[(plan.inter_no==inter_no) & (plan.start_hour==start_hour) & (plan.start_minute==start_minute)].copy().reset_index(drop=True).iloc[0] # planned row\n", + " adjusted_dur = prow[[f'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]] * 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, [f'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]] = int_parts.values\n", + " Rhist.loc[n, 'cycle'] = int_parts.sum() // 2\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)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "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": 16, + "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": [], + "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", + " + fmins[m-2] : 시뮬레이션 시작시점\n", + " + fmins[m-1] : 시뮬레이션 종료시점\n", + " output : rhistory\n", + " - recent history\n", + " - 현재시각(present_time) 이전 1시간 동안의 신호이력에 대하여 결측치 및 이상치를 처리한 결과\n", + " - 교차로번호(inter_no), 종료유닉스(end_unix), 현시시간(dur_Aj, dur_Bj), 주기(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 = [] # Recent history (1시간 이내)\n", + " for inter_no in history.inter_no.unique():\n", + " # - 5분마다 신호이력 데이터 수집해서 통합테이블 생성할때\n", + " # 1. 조회시점의 유닉스 타임을 기준으로 신호이력의 유닉스 타임이 1시간 이내인(Rhist) 데이터 수집\n", + " rhistory = history.copy() # recent history\n", + " rhistory = rhistory[(rhistory.end_unix < present_time)]\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 = plan[(plan.inter_no==inter_no) & (plan.start_hour==start_hour) & (plan.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", + " 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 - 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'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]]\n", + " # S_n : 현시시간합\n", + " S_n = ddurations.values.sum() // 2\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'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]]\n", + " S_n = ddurations.values.sum() // 2\n", + " # 비율이 0.5보다 작거나 같으면 해당 행을 삭제\n", + " if (abs(D_n - S_n) > 10) & (R_n <= 0.5):\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'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]]\n", + " S_n = ddurations.values.sum() // 2\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 = plan[(plan.inter_no==inter_no) & (plan.start_hour==start_hour) & (plan.start_minute==start_minute)].copy().reset_index(drop=True).iloc[0] # planned row\n", + " adjusted_dur = prow[[f'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]] * 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, [f'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]] = int_parts.values\n", + " Rhist.loc[n, 'cycle'] = int_parts.sum() // 2\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": 30, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2024-01-05 08:20:00\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \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_unixdura_A1dura_A2dura_A3dura_A4dura_A5dura_A6dura_A7dura_A8dura_B1dura_B2dura_B3dura_B4dura_B5dura_B6dura_B7dura_B8cycle
0201170440682030361858180003036185818000160
11771704406830402571340000402571340000170
22101704406850433965230000245865230000170
31751704406870404255330000404229590000170
417617044069103793400000037934000000170
............................................................
1461751704410269404255330000404229590000170
14717617044103103793400000037934000000170
1481781704410310383942410000383962210000160
14920217044103204611400000046114000000160
150201170441034030361858180003036185818000160
\n", + "

151 rows × 19 columns

\n", + "
" + ], + "text/plain": [ + " inter_no end_unix dura_A1 dura_A2 dura_A3 dura_A4 dura_A5 \\\n", + "0 201 1704406820 30 36 18 58 18 \n", + "1 177 1704406830 40 25 71 34 0 \n", + "2 210 1704406850 43 39 65 23 0 \n", + "3 175 1704406870 40 42 55 33 0 \n", + "4 176 1704406910 37 93 40 0 0 \n", + ".. ... ... ... ... ... ... ... \n", + "146 175 1704410269 40 42 55 33 0 \n", + "147 176 1704410310 37 93 40 0 0 \n", + "148 178 1704410310 38 39 42 41 0 \n", + "149 202 1704410320 46 114 0 0 0 \n", + "150 201 1704410340 30 36 18 58 18 \n", + "\n", + " dura_A6 dura_A7 dura_A8 dura_B1 dura_B2 dura_B3 dura_B4 dura_B5 \\\n", + "0 0 0 0 30 36 18 58 18 \n", + "1 0 0 0 40 25 71 34 0 \n", + "2 0 0 0 24 58 65 23 0 \n", + "3 0 0 0 40 42 29 59 0 \n", + "4 0 0 0 37 93 40 0 0 \n", + ".. ... ... ... ... ... ... ... ... \n", + "146 0 0 0 40 42 29 59 0 \n", + "147 0 0 0 37 93 40 0 0 \n", + "148 0 0 0 38 39 62 21 0 \n", + "149 0 0 0 46 114 0 0 0 \n", + "150 0 0 0 30 36 18 58 18 \n", + "\n", + " dura_B6 dura_B7 dura_B8 cycle \n", + "0 0 0 0 160 \n", + "1 0 0 0 170 \n", + "2 0 0 0 170 \n", + "3 0 0 0 170 \n", + "4 0 0 0 170 \n", + ".. ... ... ... ... \n", + "146 0 0 0 170 \n", + "147 0 0 0 170 \n", + "148 0 0 0 160 \n", + "149 0 0 0 160 \n", + "150 0 0 0 160 \n", + "\n", + "[151 rows x 19 columns]" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Rhists = make_rhistory(100)\n", + "Rhists" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "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'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]].sum() // 2 # 현시시간 합\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'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)] + ['cycle']]\n", + "\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", + "\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", + " phas_As = [isplit[j][0] for j in isplit.keys()]\n", + " phas_Bs = [isplit[j][1] for j in isplit.keys()]\n", + " durs_A = row[[f'dura_A{j}' for j in range(1,9)]]\n", + " durs_B = row[[f'dura_B{j}' for j in range(1,9)]]\n", + " durations = []\n", + " for j in range(1, len(isplit)+1):\n", + " ja = isplit[j][0]\n", + " jb = isplit[j][1]\n", + " if ja == jb:\n", + " durations.append(min(durs_A[ja-1], durs_B[jb-1]))\n", + " else:\n", + " durations.append(abs(durs_A[ja-1] - durs_B[ja-1]))\n", + " new_rows = pd.DataFrame({'inter_no':[inter_no] * len(durations), 'start_unix':[start_unix] * len(durations),\n", + " 'phas_A':phas_As, 'phas_B':phas_Bs, 'duration':durations})\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']) # 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", + "\n", + " # 이동류 매칭 테이블에서 진입id, 진출id를 가져와서 붙임.\n", + " for i, row in movedur.iterrows():\n", + " inter_no = row.inter_no\n", + " start_unix = row.start_unix\n", + " # incoming and outgoing edges A\n", + " move_A = row.move_A\n", + " if move_A in [17, 18]:\n", + " inc_edge_A = np.nan\n", + " out_edge_A = np.nan\n", + " else:\n", + " match_A = matching[(matching.inter_no == inter_no) & (matching.move_no == move_A)].iloc[0]\n", + " inc_edge_A = match_A.inc_edge\n", + " out_edge_A = match_A.out_edge\n", + " movedur.loc[i, ['inc_edge_A', 'out_edge_A']] = [inc_edge_A, out_edge_A]\n", + " # incoming and outgoing edges B\n", + " move_B = row.move_B\n", + " if move_B in [17, 18]:\n", + " inc_edge_B = np.nan\n", + " out_edge_B = np.nan\n", + " else:\n", + " match_B = matching[(matching.inter_no == inter_no) & (matching.move_no == move_B)].iloc[0]\n", + " inc_edge_B = match_B.inc_edge\n", + " out_edge_B = match_B.out_edge\n", + " movedur.loc[i, ['inc_edge_B', 'out_edge_B']] = [inc_edge_B, out_edge_B]\n", + "\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", + " histid['node_id'] = histid['inter_no'].map(inter2node)\n", + " histid = histid[['inter_no', 'node_id', 'start_unix', 'phas_A', 'phas_B', 'duration', 'inc_edge_A', 'out_edge_A', 'inc_edge_B', 'out_edge_B']]\n", + " histid = histid[histid.start_unix > present_time - 3600]\n", + " # 시뮬레이션 시작시각 : 현재시각 - 600\n", + " # 시뮬레이션 종료시각 : 현재시각 - 300\n", + " # 현재시각 : present_time, PT\n", + " # PT-900 ... PT-600 ... PT-300 ... PT\n", + " return histid" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "m = 120\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'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]].sum() // 2 # 현시시간 합\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'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)] + ['cycle']]\n", + "\n", + "# rhistoryy = rhistory.copy()[rhistory.inter_no==175]\n", + "# rhistoryy['diff'] = rhistoryy['start_unix'].diff()\n", + "\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", + "\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", + " phas_As = [isplit[j][0] for j in isplit.keys()]\n", + " phas_Bs = [isplit[j][1] for j in isplit.keys()]\n", + " durs_A = row[[f'dura_A{j}' for j in range(1,9)]]\n", + " durs_B = row[[f'dura_B{j}' for j in range(1,9)]]\n", + " durations = []\n", + " for j in range(1, len(isplit)+1):\n", + " ja = isplit[j][0]\n", + " jb = isplit[j][1]\n", + " if ja == jb:\n", + " durations.append(min(durs_A[ja-1], durs_B[jb-1]))\n", + " else:\n", + " durations.append(abs(durs_A[ja-1] - durs_B[ja-1]))\n", + " new_rows = pd.DataFrame({'inter_no':[inter_no] * len(durations), 'start_unix':[start_unix] * len(durations),\n", + " 'phas_A':phas_As, 'phas_B':phas_Bs, 'duration':durations})\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", + "hrhistoryy = rhistory.copy()[rhistory.inter_no==175]\n", + "hrhistoryy['diff'] = hrhistoryy['start_unix'].diff()\n", + "\n", + "# display(hrhistoryy[:60])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "for inter_no in sorted(plan.inter_no.unique()):\n", + " print(inter_no)\n", + " movement = time2movement[present_time]\n", + " movementt = movement.copy()[movement.inter_no==inter_no]\n", + " hrhistoryy = rhistory.copy()[rhistory.inter_no==inter_no]\n", + " mdts = sorted(movementt.start_unix.unique())\n", + " hdts = sorted(hrhistoryy.start_unix.unique())\n", + " import matplotlib.pyplot as plt\n", + " plt.scatter(mdts, [0]*len(mdts), c='b')\n", + " plt.scatter(hdts, [1]*len(hdts), c='r')\n", + " plt.show()\n", + " # display(movementt)\n", + " # display(hrhistoryy)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# 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']) # 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", + "\n", + "# 이동류 매칭 테이블에서 진입id, 진출id를 가져와서 붙임.\n", + "for i, row in movedur.iterrows():\n", + " inter_no = row.inter_no\n", + " start_unix = row.start_unix\n", + " # incoming and outgoing edges A\n", + " move_A = row.move_A\n", + " if move_A in [17, 18]:\n", + " inc_edge_A = np.nan\n", + " out_edge_A = np.nan\n", + " else:\n", + " match_A = matching[(matching.inter_no == inter_no) & (matching.move_no == move_A)].iloc[0]\n", + " inc_edge_A = match_A.inc_edge\n", + " out_edge_A = match_A.out_edge\n", + " movedur.loc[i, ['inc_edge_A', 'out_edge_A']] = [inc_edge_A, out_edge_A]\n", + " # incoming and outgoing edges B\n", + " move_B = row.move_B\n", + " if move_B in [17, 18]:\n", + " inc_edge_B = np.nan\n", + " out_edge_B = np.nan\n", + " else:\n", + " match_B = matching[(matching.inter_no == inter_no) & (matching.move_no == move_B)].iloc[0]\n", + " inc_edge_B = match_B.inc_edge\n", + " out_edge_B = match_B.out_edge\n", + " movedur.loc[i, ['inc_edge_B', 'out_edge_B']] = [inc_edge_B, out_edge_B]\n", + "\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", + "histid['node_id'] = histid['inter_no'].map(inter2node)\n", + "histid = histid[['inter_no', 'node_id', 'start_unix', 'phas_A', 'phas_B', 'duration', 'inc_edge_A', 'out_edge_A', 'inc_edge_B', 'out_edge_B']]\n", + "histid = histid[histid.start_unix > present_time - 3600]\n", + "# 시뮬레이션 시작시각 : 현재시각 - 600\n", + "# 시뮬레이션 종료시각 : 현재시각 - 300\n", + "# 현재시각 : present_time, PT\n", + "# PT-900 ... PT-600 ... PT-300 ... PT\n", + "\n", + "histidd = histid.copy()[histid.inter_no==175]\n", + "histidd['diff'] = histidd['start_unix'].diff()\n", + "histidd[:60]" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2024-01-05 08:20:00\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \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_nonode_idstart_unixphas_Aphas_Bdurationinc_edge_Aout_edge_Ainc_edge_Bout_edge_B
0177i217044068301140-571542809_01571542811_01571542811_02571542809_01
1177i217044068302225571542811_02571542107_01-571542809_01571542809_01
2177i217044068303371NaNNaNNaNNaN
3177i217044068304434-571542809_01571542811_01571542107_02571542809_01
4175i017044068701140-571542797_02571500487_01-571500487_01571542797_02
5175i017044068702242-571500487_01571545870_01-571542797_02571510153_01
6175i017044068703329571545870_02571510153_01571545870_02571542797_02
7175i017044068703426571545870_02571510153_01571510153_02571545870_01
8175i017044068704433571510153_02571500487_01571510153_02571545870_01
9176i117044069101137-571542810_01-571542797_02.99571542797_02.99571542810_01
10176i117044069102293-571542810_01-571542797_02.99-571542810_01571543469_01
11176i117044069103340571543469_02-571542797_02.99NaNNaN
12178i317044069501138571540304_02571556450_01571556450_02571540304_01
13178i317044069502239571556450_02571500475_01571540304_02571540303_01
14178i317044069503342571540303_02.21571556450_01571540303_02.21571500475_01
15178i317044069504421-571500475_01571540303_01-571500475_01571540304_01
16202i917044069501146571510152_02-571510152_01571510152_01571510152_01.65
17202i9170440695022114NaNNaNNaNNaN
18177i217044070001140-571542809_01571542811_01571542811_02571542809_01
19177i217044070002225571542811_02571542107_01-571542809_01571542809_01
20177i217044070003371NaNNaNNaNNaN
21177i217044070004434-571542809_01571542811_01571542107_02571542809_01
22175i017044070401140-571542797_02571500487_01-571500487_01571542797_02
23175i017044070402242-571500487_01571545870_01-571542797_02571510153_01
24175i017044070403329571545870_02571510153_01571545870_02571542797_02
25175i017044070403426571545870_02571510153_01571510153_02571545870_01
26175i017044070404433571510153_02571500487_01571510153_02571545870_01
27176i117044070801137-571542810_01-571542797_02.99571542797_02.99571542810_01
28176i117044070802293-571542810_01-571542797_02.99-571542810_01571543469_01
29176i117044070803340571543469_02-571542797_02.99NaNNaN
\n", + "
" + ], + "text/plain": [ + " inter_no node_id start_unix phas_A phas_B duration inc_edge_A \\\n", + "0 177 i2 1704406830 1 1 40 -571542809_01 \n", + "1 177 i2 1704406830 2 2 25 571542811_02 \n", + "2 177 i2 1704406830 3 3 71 NaN \n", + "3 177 i2 1704406830 4 4 34 -571542809_01 \n", + "4 175 i0 1704406870 1 1 40 -571542797_02 \n", + "5 175 i0 1704406870 2 2 42 -571500487_01 \n", + "6 175 i0 1704406870 3 3 29 571545870_02 \n", + "7 175 i0 1704406870 3 4 26 571545870_02 \n", + "8 175 i0 1704406870 4 4 33 571510153_02 \n", + "9 176 i1 1704406910 1 1 37 -571542810_01 \n", + "10 176 i1 1704406910 2 2 93 -571542810_01 \n", + "11 176 i1 1704406910 3 3 40 571543469_02 \n", + "12 178 i3 1704406950 1 1 38 571540304_02 \n", + "13 178 i3 1704406950 2 2 39 571556450_02 \n", + "14 178 i3 1704406950 3 3 42 571540303_02.21 \n", + "15 178 i3 1704406950 4 4 21 -571500475_01 \n", + "16 202 i9 1704406950 1 1 46 571510152_02 \n", + "17 202 i9 1704406950 2 2 114 NaN \n", + "18 177 i2 1704407000 1 1 40 -571542809_01 \n", + "19 177 i2 1704407000 2 2 25 571542811_02 \n", + "20 177 i2 1704407000 3 3 71 NaN \n", + "21 177 i2 1704407000 4 4 34 -571542809_01 \n", + "22 175 i0 1704407040 1 1 40 -571542797_02 \n", + "23 175 i0 1704407040 2 2 42 -571500487_01 \n", + "24 175 i0 1704407040 3 3 29 571545870_02 \n", + "25 175 i0 1704407040 3 4 26 571545870_02 \n", + "26 175 i0 1704407040 4 4 33 571510153_02 \n", + "27 176 i1 1704407080 1 1 37 -571542810_01 \n", + "28 176 i1 1704407080 2 2 93 -571542810_01 \n", + "29 176 i1 1704407080 3 3 40 571543469_02 \n", + "\n", + " out_edge_A inc_edge_B out_edge_B \n", + "0 571542811_01 571542811_02 571542809_01 \n", + "1 571542107_01 -571542809_01 571542809_01 \n", + "2 NaN NaN NaN \n", + "3 571542811_01 571542107_02 571542809_01 \n", + "4 571500487_01 -571500487_01 571542797_02 \n", + "5 571545870_01 -571542797_02 571510153_01 \n", + "6 571510153_01 571545870_02 571542797_02 \n", + "7 571510153_01 571510153_02 571545870_01 \n", + "8 571500487_01 571510153_02 571545870_01 \n", + "9 -571542797_02.99 571542797_02.99 571542810_01 \n", + "10 -571542797_02.99 -571542810_01 571543469_01 \n", + "11 -571542797_02.99 NaN NaN \n", + "12 571556450_01 571556450_02 571540304_01 \n", + "13 571500475_01 571540304_02 571540303_01 \n", + "14 571556450_01 571540303_02.21 571500475_01 \n", + "15 571540303_01 -571500475_01 571540304_01 \n", + "16 -571510152_01 571510152_01 571510152_01.65 \n", + "17 NaN NaN NaN \n", + "18 571542811_01 571542811_02 571542809_01 \n", + "19 571542107_01 -571542809_01 571542809_01 \n", + "20 NaN NaN NaN \n", + "21 571542811_01 571542107_02 571542809_01 \n", + "22 571500487_01 -571500487_01 571542797_02 \n", + "23 571545870_01 -571542797_02 571510153_01 \n", + "24 571510153_01 571545870_02 571542797_02 \n", + "25 571510153_01 571510153_02 571545870_01 \n", + "26 571500487_01 571510153_02 571545870_01 \n", + "27 -571542797_02.99 571542797_02.99 571542810_01 \n", + "28 -571542797_02.99 -571542810_01 571543469_01 \n", + "29 -571542797_02.99 NaN NaN " + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "make_histid(100)[:30]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "inter_no = 175\n", + "rhist = make_histid(100)\n", + "rhis = rhist.copy()[rhist.inter_no==inter_no]\n", + "rhis['diff'] = rhis['start_unix'].diff()\n", + "rhis[:60]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "inter_no = 175\n", + "histid = make_histid(100)\n", + "his = histid.copy()[histid.inter_no==inter_no]\n", + "his['diff'] = his['start_unix'].diff()\n", + "his[:60]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "for m in range(30, 288):\n", + " print(m)\n", + " make_histid(m).to_csv(f'../../Data/tables/histids/histids_{fmins[m]}.csv')" + ] + } + ], + "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 +} diff --git a/Analysis/0109_preprocess/0122_preprocess_9.6.ipynb b/Analysis/0109_preprocess/0122_preprocess_9.6.ipynb new file mode 100644 index 000000000..0294b6f09 --- /dev/null +++ b/Analysis/0109_preprocess/0122_preprocess_9.6.ipynb @@ -0,0 +1,7526 @@ +{ + "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%|██████████| 17281/17281 [00:13<00:00, 1257.14it/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": 45, + "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": 45, + "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": 46, + "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": 46, + "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": 47, + "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
01751A8179004-571542797_02571500487_01i0
11751B4003176-571500487_01571542797_02i0
21752A7001095-571500487_01571545870_01i0
31752B3179270-571542797_02571510153_01i0
41753A6090270571545870_02571510153_01i0
51753B1090180571545870_02571542797_02i0
61754A5268000571510153_02571500487_01i0
71754B2270090571510153_02571545870_01i0
81761A8180000-571542810_01-571542797_02.99i1
91761B4359180571542797_02.99571542810_01i1
101762A8180000-571542810_01-571542797_02.99i1
111762B3180270-571542810_01571543469_01i1
121763A5270356571543469_02-571542797_02.99i1
131763B18NaNNaNNaNNaNNaNNaNi1
141771A8180000-571542809_01571542811_01i2
151771B4001176571542811_02571542809_01i2
161772A7000090571542811_02571542107_01i2
171772B3179270-571542809_01571542809_01i2
181773A17NaNNaNNaNNaNNaNNaNi2
191773B18NaNNaNNaNNaNNaNNaNi2
201774A5268000-571542809_01571542811_01i2
211774B1090180571542107_02571542809_01i2
221781A8180000571540304_02571556450_01i3
231781B4000180571556450_02571540304_01i3
241782A7000090571556450_02571500475_01i3
251782B3180270571540304_02571540303_01i3
261783A5270000571540303_02.21571556450_01i3
271783B2270090571540303_02.21571500475_01i3
281784A6090270-571500475_01571540303_01i3
291784B1090180-571500475_01571540304_01i3
302011A8180000-571500569_01571500583_02i8
312011B3180270-571500569_01571500618_01i8
322012A5270000571500618_02571500583_02i8
332012B2270090571500618_02571500617_01i8
342013A6090270571500617_02571500618_01i8
352013B2270090571500618_02571500617_01i8
362014A6090270571500617_02571500618_01i8
372014B1090180571500617_02571500569_01i8
382015A7000090571500583_01571500617_01i8
392015B4000180571500583_01571500569_01i8
402021A6090270571510152_02-571510152_01i9
412021B2270090571510152_01571510152_01.65i9
422022A17NaNNaNNaNNaNNaNNaNi9
432022B18NaNNaNNaNNaNNaNNaNi9
442061A8180000-571511538_02571542073_02i7
452061B4000180571542073_01571511538_02i7
462062A17NaNNaNNaNNaNNaNNaNi7
472062B18NaNNaNNaNNaNNaNNaNi7
482063A8180000-571511538_02571542073_02i7
492063B4000180571542073_01571511538_02i7
502064A17NaNNaNNaNNaNNaNNaNi7
512064B18NaNNaNNaNNaNNaNNaNi7
522101A6090270-571542115_01571500535_01i6
532101B18NaNNaNNaNNaNNaNNaNi6
542102A5268000571500535_02.18571511538_01i6
552102B2270090571500535_02.18571542115_01i6
562103A7359090571511538_02.121571542115_01i6
572103B4000180571511538_02.121571500585_01i6
582104A8180000571500585_02571511538_01i6
592104B3180270571500585_02571500535_01i6
\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 \n", + "\n", + " inc_edge out_edge node_id \n", + "0 -571542797_02 571500487_01 i0 \n", + "1 -571500487_01 571542797_02 i0 \n", + "2 -571500487_01 571545870_01 i0 \n", + "3 -571542797_02 571510153_01 i0 \n", + "4 571545870_02 571510153_01 i0 \n", + "5 571545870_02 571542797_02 i0 \n", + "6 571510153_02 571500487_01 i0 \n", + "7 571510153_02 571545870_01 i0 \n", + "8 -571542810_01 -571542797_02.99 i1 \n", + "9 571542797_02.99 571542810_01 i1 \n", + "10 -571542810_01 -571542797_02.99 i1 \n", + "11 -571542810_01 571543469_01 i1 \n", + "12 571543469_02 -571542797_02.99 i1 \n", + "13 NaN NaN i1 \n", + "14 -571542809_01 571542811_01 i2 \n", + "15 571542811_02 571542809_01 i2 \n", + "16 571542811_02 571542107_01 i2 \n", + "17 -571542809_01 571542809_01 i2 \n", + "18 NaN NaN i2 \n", + "19 NaN NaN i2 \n", + "20 -571542809_01 571542811_01 i2 \n", + "21 571542107_02 571542809_01 i2 \n", + "22 571540304_02 571556450_01 i3 \n", + "23 571556450_02 571540304_01 i3 \n", + "24 571556450_02 571500475_01 i3 \n", + "25 571540304_02 571540303_01 i3 \n", + "26 571540303_02.21 571556450_01 i3 \n", + "27 571540303_02.21 571500475_01 i3 \n", + "28 -571500475_01 571540303_01 i3 \n", + "29 -571500475_01 571540304_01 i3 \n", + "30 -571500569_01 571500583_02 i8 \n", + "31 -571500569_01 571500618_01 i8 \n", + "32 571500618_02 571500583_02 i8 \n", + "33 571500618_02 571500617_01 i8 \n", + "34 571500617_02 571500618_01 i8 \n", + "35 571500618_02 571500617_01 i8 \n", + "36 571500617_02 571500618_01 i8 \n", + "37 571500617_02 571500569_01 i8 \n", + "38 571500583_01 571500617_01 i8 \n", + "39 571500583_01 571500569_01 i8 \n", + "40 571510152_02 -571510152_01 i9 \n", + "41 571510152_01 571510152_01.65 i9 \n", + "42 NaN NaN i9 \n", + "43 NaN NaN i9 \n", + "44 -571511538_02 571542073_02 i7 \n", + "45 571542073_01 571511538_02 i7 \n", + "46 NaN NaN i7 \n", + "47 NaN NaN i7 \n", + "48 -571511538_02 571542073_02 i7 \n", + "49 571542073_01 571511538_02 i7 \n", + "50 NaN NaN i7 \n", + "51 NaN NaN i7 \n", + "52 -571542115_01 571500535_01 i6 \n", + "53 NaN NaN i6 \n", + "54 571500535_02.18 571511538_01 i6 \n", + "55 571500535_02.18 571542115_01 i6 \n", + "56 571511538_02.121 571542115_01 i6 \n", + "57 571511538_02.121 571500585_01 i6 \n", + "58 571500585_02 571511538_01 i6 \n", + "59 571500585_02 571500535_01 i6 " + ] + }, + "execution_count": 47, + "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.sort_values(by=['inter_no','phase_no','ring_type']).reset_index(drop=True)\n", + "match5" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array(['u00', 'u20', 'u30', 'u31', 'u32', 'u60'], dtype=object)" + ] + }, + "execution_count": 48, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# 유턴/연동교차로에 대하여 진입ID, 진출ID 부여\n", + "node2inter = dict(zip(inter_node['node_id'], inter_node['inter_no']))\n", + "\n", + "uturn = pd.read_csv('../../Data/tables/child_uturn.csv')\n", + "coord = pd.read_csv('../../Data/tables/child_coord.csv')\n", + "\n", + "child_ids = inter_node[inter_node.inter_type=='child'].node_id.unique()\n", + "ch2pa = {} # child to parent\n", + "for child_id in child_ids:\n", + " parent_no = inter_node[inter_node.node_id==child_id].inter_no.iloc[0]\n", + " sub_inter_node = inter_node[inter_node.inter_no==parent_no]\n", + " ch2pa[child_id] = sub_inter_node[sub_inter_node.inter_type=='parent'].iloc[0].node_id\n", + "directions = ['북', '북동', '동', '남동', '남', '남서', '서', '북서'] # 정북기준 시계방향으로 8방향\n", + "u_ids = uturn.child_id.unique()\n", + "u_ids" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "u00 i0 좌회전시 북\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \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
01751A8179004NaNNaNu00
11751B4003176NaNNaNu00
21752A19001095571500487_02571500487_01.32u00
31752B3179270NaNNaNu00
41753A6090270NaNNaNu00
51753B1090180NaNNaNu00
61754A5268000NaNNaNu00
71754B2270090NaNNaNu00
\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 19 북 동 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", + "\n", + " inc_edge out_edge node_id \n", + "0 NaN NaN u00 \n", + "1 NaN NaN u00 \n", + "2 571500487_02 571500487_01.32 u00 \n", + "3 NaN NaN u00 \n", + "4 NaN NaN u00 \n", + "5 NaN NaN u00 \n", + "6 NaN NaN u00 \n", + "7 NaN NaN u00 " + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "u20 i2 보행신호시 북\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \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
01771A8180000NaNNaNu20
11771B4001176NaNNaNu20
21772A7000090NaNNaNu20
31772B3179270NaNNaNu20
41773A17NaNNaNNaNNaN571542810_01.51571542810_02u20
51773B18NaNNaNNaNNaNNaNNaNu20
61774A5268000NaNNaNu20
71774B1090180NaNNaNu20
\n", + "
" + ], + "text/plain": [ + " inter_no phase_no ring_type move_no inc_dir out_dir inc_angle out_angle \\\n", + "0 177 1 A 8 남 북 180 000 \n", + "1 177 1 B 4 북 남 001 176 \n", + "2 177 2 A 7 북 동 000 090 \n", + "3 177 2 B 3 남 서 179 270 \n", + "4 177 3 A 17 NaN NaN NaN NaN \n", + "5 177 3 B 18 NaN NaN NaN NaN \n", + "6 177 4 A 5 서 북 268 000 \n", + "7 177 4 B 1 동 남 090 180 \n", + "\n", + " inc_edge out_edge node_id \n", + "0 NaN NaN u20 \n", + "1 NaN NaN u20 \n", + "2 NaN NaN u20 \n", + "3 NaN NaN u20 \n", + "4 571542810_01.51 571542810_02 u20 \n", + "5 NaN NaN u20 \n", + "6 NaN NaN u20 \n", + "7 NaN NaN u20 " + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "u30 i3 보행신호시 북\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \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
01781A8180000NaNNaNu30
11781B4000180NaNNaNu30
21782A7000090NaNNaNu30
31782B3180270NaNNaNu30
41783A5270000NaNNaNu30
51783B2270090NaNNaNu30
61784A19090270571556452_01571556452_02u30
71784B1090180NaNNaNu30
\n", + "
" + ], + "text/plain": [ + " inter_no phase_no ring_type move_no inc_dir out_dir inc_angle out_angle \\\n", + "0 178 1 A 8 남 북 180 000 \n", + "1 178 1 B 4 북 남 000 180 \n", + "2 178 2 A 7 북 동 000 090 \n", + "3 178 2 B 3 남 서 180 270 \n", + "4 178 3 A 5 서 북 270 000 \n", + "5 178 3 B 2 서 동 270 090 \n", + "6 178 4 A 19 동 서 090 270 \n", + "7 178 4 B 1 동 남 090 180 \n", + "\n", + " inc_edge out_edge node_id \n", + "0 NaN NaN u30 \n", + "1 NaN NaN u30 \n", + "2 NaN NaN u30 \n", + "3 NaN NaN u30 \n", + "4 NaN NaN u30 \n", + "5 NaN NaN u30 \n", + "6 571556452_01 571556452_02 u30 \n", + "7 NaN NaN u30 " + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "u31 i3 보행신호시 동\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \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
01781A19180000571500475_02571500475_01.26u31
11781B4000180NaNNaNu31
21782A7000090NaNNaNu31
31782B3180270NaNNaNu31
41783A5270000NaNNaNu31
51783B2270090NaNNaNu31
61784A6090270NaNNaNu31
71784B1090180NaNNaNu31
\n", + "
" + ], + "text/plain": [ + " inter_no phase_no ring_type move_no inc_dir out_dir inc_angle out_angle \\\n", + "0 178 1 A 19 남 북 180 000 \n", + "1 178 1 B 4 북 남 000 180 \n", + "2 178 2 A 7 북 동 000 090 \n", + "3 178 2 B 3 남 서 180 270 \n", + "4 178 3 A 5 서 북 270 000 \n", + "5 178 3 B 2 서 동 270 090 \n", + "6 178 4 A 6 동 서 090 270 \n", + "7 178 4 B 1 동 남 090 180 \n", + "\n", + " inc_edge out_edge node_id \n", + "0 571500475_02 571500475_01.26 u31 \n", + "1 NaN NaN u31 \n", + "2 NaN NaN u31 \n", + "3 NaN NaN u31 \n", + "4 NaN NaN u31 \n", + "5 NaN NaN u31 \n", + "6 NaN NaN u31 \n", + "7 NaN NaN u31 " + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "u32 i3 보행신호시 서\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \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
01781A8180000NaNNaNu32
11781B19000180571540303_02-571540303_02u32
21782A7000090NaNNaNu32
31782B3180270NaNNaNu32
41783A5270000NaNNaNu32
51783B2270090NaNNaNu32
61784A6090270NaNNaNu32
71784B1090180NaNNaNu32
\n", + "
" + ], + "text/plain": [ + " inter_no phase_no ring_type move_no inc_dir out_dir inc_angle out_angle \\\n", + "0 178 1 A 8 남 북 180 000 \n", + "1 178 1 B 19 북 남 000 180 \n", + "2 178 2 A 7 북 동 000 090 \n", + "3 178 2 B 3 남 서 180 270 \n", + "4 178 3 A 5 서 북 270 000 \n", + "5 178 3 B 2 서 동 270 090 \n", + "6 178 4 A 6 동 서 090 270 \n", + "7 178 4 B 1 동 남 090 180 \n", + "\n", + " inc_edge out_edge node_id \n", + "0 NaN NaN u32 \n", + "1 571540303_02 -571540303_02 u32 \n", + "2 NaN NaN u32 \n", + "3 NaN NaN u32 \n", + "4 NaN NaN u32 \n", + "5 NaN NaN u32 \n", + "6 NaN NaN u32 \n", + "7 NaN NaN u32 " + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "u60 i6 직좌시 서\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \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
02101A6090270NaNNaNu60
12101B18NaNNaNNaNNaNNaNNaNu60
22102A19268000571500535_02-571500535_02u60
32102B19270090571500535_02-571500535_02u60
42103A7359090NaNNaNu60
52103B4000180NaNNaNu60
62104A8180000NaNNaNu60
72104B3180270NaNNaNu60
\n", + "
" + ], + "text/plain": [ + " inter_no phase_no ring_type move_no inc_dir out_dir inc_angle out_angle \\\n", + "0 210 1 A 6 동 서 090 270 \n", + "1 210 1 B 18 NaN NaN NaN NaN \n", + "2 210 2 A 19 서 북 268 000 \n", + "3 210 2 B 19 서 동 270 090 \n", + "4 210 3 A 7 북 동 359 090 \n", + "5 210 3 B 4 북 남 000 180 \n", + "6 210 4 A 8 남 북 180 000 \n", + "7 210 4 B 3 남 서 180 270 \n", + "\n", + " inc_edge out_edge node_id \n", + "0 NaN NaN u60 \n", + "1 NaN NaN u60 \n", + "2 571500535_02 -571500535_02 u60 \n", + "3 571500535_02 -571500535_02 u60 \n", + "4 NaN NaN u60 \n", + "5 NaN NaN u60 \n", + "6 NaN NaN u60 \n", + "7 NaN NaN u60 " + ] + }, + "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", + "
inter_nophase_noring_typemove_noinc_dirout_dirinc_angleout_angleinc_edgeout_edgenode_id
01781A20NaNNaNNaNNaNNaNNaNc30
11781B20NaNNaNNaNNaNNaNNaNc30
21782A20NaNNaNNaNNaN571542116_01-571542116_02.96c30
31782B20NaNNaNNaNNaN571542116_02.96571542116_02.164c30
41783A20NaNNaNNaNNaN571542116_01-571542116_02.96c30
51783B20NaNNaNNaNNaN571542116_02.96571542116_02.164c30
61784A20NaNNaNNaNNaN571542116_01-571542116_02.96c30
71784B20NaNNaNNaNNaN571542116_02.96571542116_02.164c30
\n", + "
" + ], + "text/plain": [ + " inter_no phase_no ring_type move_no inc_dir out_dir inc_angle \\\n", + "0 178 1 A 20 NaN NaN NaN \n", + "1 178 1 B 20 NaN NaN NaN \n", + "2 178 2 A 20 NaN NaN NaN \n", + "3 178 2 B 20 NaN NaN NaN \n", + "4 178 3 A 20 NaN NaN NaN \n", + "5 178 3 B 20 NaN NaN NaN \n", + "6 178 4 A 20 NaN NaN NaN \n", + "7 178 4 B 20 NaN NaN NaN \n", + "\n", + " out_angle inc_edge out_edge node_id \n", + "0 NaN NaN NaN c30 \n", + "1 NaN NaN NaN c30 \n", + "2 NaN 571542116_01 -571542116_02.96 c30 \n", + "3 NaN 571542116_02.96 571542116_02.164 c30 \n", + "4 NaN 571542116_01 -571542116_02.96 c30 \n", + "5 NaN 571542116_02.96 571542116_02.164 c30 \n", + "6 NaN 571542116_01 -571542116_02.96 c30 \n", + "7 NaN 571542116_02.96 571542116_02.164 c30 " + ] + }, + "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", + "
inter_nophase_noring_typemove_noinc_dirout_dirinc_angleout_angleinc_edgeout_edgenode_id
01751A8179004-571542797_02571500487_01i0
11751B4003176-571500487_01571542797_02i0
21752A7001095-571500487_01571545870_01i0
31752B3179270-571542797_02571510153_01i0
41753A6090270571545870_02571510153_01i0
....................................
32102B19270090571500535_02-571500535_02u60
42103A7359090NaNNaNu60
52103B4000180NaNNaNu60
62104A8180000NaNNaNu60
72104B3180270NaNNaNu60
\n", + "

116 rows × 11 columns

\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", + ".. ... ... ... ... ... ... ... ... \n", + "3 210 2 B 19 서 동 270 090 \n", + "4 210 3 A 7 북 동 359 090 \n", + "5 210 3 B 4 북 남 000 180 \n", + "6 210 4 A 8 남 북 180 000 \n", + "7 210 4 B 3 남 서 180 270 \n", + "\n", + " inc_edge out_edge node_id \n", + "0 -571542797_02 571500487_01 i0 \n", + "1 -571500487_01 571542797_02 i0 \n", + "2 -571500487_01 571545870_01 i0 \n", + "3 -571542797_02 571510153_01 i0 \n", + "4 571545870_02 571510153_01 i0 \n", + ".. ... ... ... \n", + "3 571500535_02 -571500535_02 u60 \n", + "4 NaN NaN u60 \n", + "5 NaN NaN u60 \n", + "6 NaN NaN u60 \n", + "7 NaN NaN u60 \n", + "\n", + "[116 rows x 11 columns]" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# 유턴/연동교차로에 대하여 진입ID, 진출ID 부여\n", + "node2inter = dict(zip(inter_node['node_id'], inter_node['inter_no']))\n", + "\n", + "uturn = pd.read_csv('../../Data/tables/child_uturn.csv')\n", + "coord = pd.read_csv('../../Data/tables/child_coord.csv')\n", + "child_ids = inter_node[inter_node.inter_type=='child'].node_id.unique()\n", + "ch2pa = {} # child to parent\n", + "for child_id in child_ids:\n", + " parent_no = inter_node[inter_node.node_id==child_id].inter_no.iloc[0]\n", + " sub_inter_node = inter_node[inter_node.inter_no==parent_no]\n", + " ch2pa[child_id] = sub_inter_node[sub_inter_node.inter_type=='parent'].iloc[0].node_id\n", + "directions = ['북', '북동', '동', '남동', '남', '남서', '서', '북서'] # 정북기준 시계방향으로 8방향\n", + "u_ids = uturn.child_id.unique()\n", + "# 각 child uturn node에 대하여 (inc_edge_id, out_edge_id) 부여\n", + "cmatches = []\n", + "for _, row in uturn.iterrows():\n", + " child_id = row.child_id\n", + " parent_id = row.parent_id\n", + " direction = row.direction\n", + " condition = row.condition\n", + " inc_edge_id = row.inc_edge\n", + " out_edge_id = row.out_edge\n", + " ind = directions.index(direction)\n", + " if condition == \"좌회전시\":\n", + " print(child_id, parent_id, condition, direction)\n", + " inc_dire = direction\n", + " out_dire_A = out_dire_B = directions[(ind + 2) % len(directions)]\n", + " elif condition == \"직진시\":\n", + " print(child_id, parent_id, condition, direction)\n", + " inc_dire = direction\n", + " out_dire_A = out_dire_B = directions[(ind + 4) % len(directions)]\n", + " elif condition == \"직좌시\":\n", + " print(child_id, parent_id, condition, direction)\n", + " inc_dire = direction\n", + " out_dire_A = directions[(ind + 2) % len(directions)]\n", + " out_dire_B = directions[(ind + 4) % len(directions)]\n", + " elif condition == \"보행신호시\":\n", + " print(child_id, parent_id, condition, direction)\n", + " inc_dire = directions[(ind + 2) % len(directions)]\n", + " out_dire_A = directions[(ind - 2) % len(directions)]\n", + " out_dire_B = directions[(ind - 2) % len(directions)]\n", + " cmatch = match5.copy()[match5.node_id==parent_id] # match dataframe for a child node\n", + " cmatch = cmatch.sort_values(by=['phase_no', 'ring_type']).reset_index(drop=True)\n", + " cmatch['node_id'] = child_id\n", + " cmatch[['inc_edge', 'out_edge']] = np.nan\n", + " if condition == '직좌시':\n", + " ap = cmatch[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_A)].phase_no.iloc[0]\n", + " bp = cmatch[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_B)].phase_no.iloc[0]\n", + " # 직진과 좌회전이 같은 현시에 있는 경우에만 (inc_edge_id, out_edge_id)를 부여한다.\n", + " if ap == bp:\n", + " cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_A), ['inc_edge', 'out_edge']] = [inc_edge_id, out_edge_id]\n", + " cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_B), ['inc_edge', 'out_edge']] = [inc_edge_id, out_edge_id]\n", + " elif condition == '보행신호시':\n", + " cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_A), ['inc_edge', 'out_edge']] = [inc_edge_id, out_edge_id]\n", + " cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_B), ['inc_edge', 'out_edge']] = [inc_edge_id, out_edge_id]\n", + " # 이동류번호가 17(보행신호)이면서 유턴노드방향으로 가는 신호가 없으면 (inc_edge_id, out_edge_id)를 부여한다.\n", + " cmatch.loc[(cmatch.move_no==17) & (cmatch.out_dir!=direction), ['inc_edge', 'out_edge']] = [inc_edge_id, out_edge_id]\n", + " else:\n", + " cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_A), ['inc_edge', 'out_edge']] = [inc_edge_id, out_edge_id]\n", + " cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_B), ['inc_edge', 'out_edge']] = [inc_edge_id, out_edge_id]\n", + " # 유턴신호의 이동류번호를 19로 부여한다.\n", + " cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_A), 'move_no'] = 19\n", + " cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_B), 'move_no'] = 19\n", + " display(cmatch)\n", + " cmatches.append(cmatch)\n", + "\n", + "# 각 child coordination node에 대하여 (inc_edge_id, out_edge_id) 부여\n", + "coord['inter_no'] = coord['parent_id'].map(node2inter)\n", + "coord = coord.rename(columns={'child_id':'node_id'})\n", + "coord[['inc_dir', 'out_dir', 'inc_angle','out_angle']] = np.nan\n", + "coord['move_no'] = 20\n", + "coord = coord[['inter_no', 'phase_no', 'ring_type', 'move_no', 'inc_dir', 'out_dir', 'inc_angle','out_angle', 'inc_edge', 'out_edge', 'node_id']]\n", + "# display(coord)\n", + "cmatches = pd.concat(cmatches)\n", + "display(coord)\n", + "match6 = pd.concat([match5, cmatches, coord]).drop_duplicates().sort_values(by=['inter_no', 'node_id', 'phase_no', 'ring_type'])\n", + "# with pd.option_context('display.max_rows', None, 'display.max_columns', None):\n", + "match6.to_csv('../../Data/tables/matching/match6.csv')\n", + "display(match6)" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "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", + "
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
........................
692108571500585_02571511538_01i6
7021021571511538_02.121571500535_01i6
7121021571500535_02.18571500585_01i6
7221021571500585_02571542115_01i6
7321021-571542115_01571511538_01i6
\n", + "

74 rows × 7 columns

\n", + "
" + ], + "text/plain": [ + " inter_no move_no inc_dir out_dir inc_edge out_edge node_id\n", + "0 175 1 동 남 571545870_02 571542797_02 i0\n", + "1 175 2 서 동 571510153_02 571545870_01 i0\n", + "2 175 3 남 서 -571542797_02 571510153_01 i0\n", + "3 175 4 북 남 -571500487_01 571542797_02 i0\n", + "4 175 5 서 북 571510153_02 571500487_01 i0\n", + ".. ... ... ... ... ... ... ...\n", + "69 210 8 남 북 571500585_02 571511538_01 i6\n", + "70 210 21 북 서 571511538_02.121 571500535_01 i6\n", + "71 210 21 서 남 571500535_02.18 571500585_01 i6\n", + "72 210 21 남 동 571500585_02 571542115_01 i6\n", + "73 210 21 동 북 -571542115_01 571511538_01 i6\n", + "\n", + "[74 rows x 7 columns]" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# 이동류 매칭\n", + "# 각 교차로에 대하여, 가능한 모든 이동류(1~18, 21)에 대한 진입·진출엣지ID를 지정한다.\n", + "# 모든 이동류에 대해 지정하므로, 시차제시 이전과 다른 이동류가 등장하더라도 항상 진입·진출 엣지 ID를 지정할 수 있다.\n", + "match7 = match6.copy()\n", + "match7 = match7[['inter_no', 'move_no', 'inc_dir', 'out_dir', 'inc_edge', 'out_edge', 'node_id']]\n", + "\n", + "parent_ids = sorted(inter_node[inter_node.inter_type=='parent'].node_id.unique())\n", + "child_ids = sorted(inter_node[inter_node.inter_type=='child'].node_id.unique())\n", + "\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 node_id in parent_ids:\n", + " dires = match7[match7.node_id == node_id][['inc_dir','out_dir']].values.flatten()\n", + " dires = {dire for dire in dires if type(dire)==str}\n", + " pdires[node_id] = dires\n", + "# (3) 각 (교차로, 진입방향) 별 진입id 목록 : inc2id (incoming direction to incoming edge_id)\n", + "inc2id = {}\n", + "for node_id in parent_ids:\n", + " for inc_dir in pdires[node_id]:\n", + " df = match7[(match7.node_id==node_id) & (match7.inc_dir==inc_dir)]\n", + " inc2id[(node_id, inc_dir)] = df.inc_edge.iloc[0]\n", + "# (4) 각 (교차로, 진출방향) 별 진출id 목록 : out2id (outgoing direction to outgoing edge_id)\n", + "out2id = {}\n", + "for node_id in parent_ids:\n", + " for out_dir in pdires[node_id]:\n", + " df = match7[(match7.node_id==node_id) & (match7.out_dir==out_dir)]\n", + " out2id[(node_id, out_dir)] = df.out_edge.iloc[0]\n", + "# (5) 각 교차로별 가능한 (진입방향, 진출방향) 목록 : pflow (possible flows)\n", + "pflow = {}\n", + "for node_id in parent_ids:\n", + " pflow[node_id] = [flow for flow in flows if set(flow).issubset(pdires[node_id])]\n", + "# (6) 가능한 이동류에 대하여 진입id, 진출id 배정 : matching\n", + "node2inter = dict(zip(match7['node_id'], match7['inter_no']))\n", + "dires_right = ['북', '서', '남', '동', '북'] # ex (북, 서), (서, 남) 등은 우회전 flow\n", + "matching = []\n", + "for node_id in parent_ids:\n", + " inter_no = node2inter[node_id]\n", + " # 좌회전과 직진(1 ~ 16)\n", + " for (inc_dir, out_dir) in pflow[node_id]:\n", + " move_no = nema[(nema.inc_dir==inc_dir) & (nema.out_dir==out_dir)].move_no.iloc[0]\n", + " inc_edge = inc2id[(node_id, inc_dir)]\n", + " out_edge = out2id[(node_id, 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[node_id]):\n", + " inc_edge = inc2id[(node_id, inc_dir)]\n", + " out_edge = out2id[(node_id, 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.append(match7[match7.node_id.isin(child_ids)])\n", + "matching = pd.concat(matching)\n", + "matching = matching.dropna().sort_values(by=['inter_no', 'node_id', 'move_no']).reset_index(drop=True)\n", + "matching['move_no'] = matching['move_no'].astype(int)\n", + "matching.to_csv('../../Data/tables/matching/matching.csv')\n", + "display(matching)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# B. 5초 간격으로 이동류번호 수집" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": {}, + "outputs": [], + "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" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": {}, + "outputs": [], + "source": [ + "# # 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": 53, + "metadata": {}, + "outputs": [], + "source": [ + "plan = pd.read_csv('../../Data/tables/plan.csv', index_col=0)\n", + "history = pd.read_csv('../../Data/tables/history.csv', index_col=0)" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "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": 54, + "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": 55, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2024-01-05 03:20:00\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \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_unixdura_A1dura_A2dura_A3dura_A4dura_A5dura_A6dura_A7dura_A8dura_B1dura_B2dura_B3dura_B4dura_B5dura_B6dura_B7dura_B8cycle
601781704388800383940230000383940230000140
60201170438880024241758170002424175817000140
6020217043888003910100000039101000000140
702061704388800333526260000333526260000120
561771704388801362068260000362068260000150
............................................................
782101704392159432956220000244856220000150
841781704392160383940230000383940230000140
84201170439216024241758170002424175817000140
982061704392160333526260000333526260000120
8420217043922113910100000039101000000140
\n", + "

194 rows × 19 columns

\n", + "
" + ], + "text/plain": [ + " inter_no start_unix dura_A1 dura_A2 dura_A3 dura_A4 dura_A5 \\\n", + "60 178 1704388800 38 39 40 23 0 \n", + "60 201 1704388800 24 24 17 58 17 \n", + "60 202 1704388800 39 101 0 0 0 \n", + "70 206 1704388800 33 35 26 26 0 \n", + "56 177 1704388801 36 20 68 26 0 \n", + ".. ... ... ... ... ... ... ... \n", + "78 210 1704392159 43 29 56 22 0 \n", + "84 178 1704392160 38 39 40 23 0 \n", + "84 201 1704392160 24 24 17 58 17 \n", + "98 206 1704392160 33 35 26 26 0 \n", + "84 202 1704392211 39 101 0 0 0 \n", + "\n", + " dura_A6 dura_A7 dura_A8 dura_B1 dura_B2 dura_B3 dura_B4 dura_B5 \\\n", + "60 0 0 0 38 39 40 23 0 \n", + "60 0 0 0 24 24 17 58 17 \n", + "60 0 0 0 39 101 0 0 0 \n", + "70 0 0 0 33 35 26 26 0 \n", + "56 0 0 0 36 20 68 26 0 \n", + ".. ... ... ... ... ... ... ... ... \n", + "78 0 0 0 24 48 56 22 0 \n", + "84 0 0 0 38 39 40 23 0 \n", + "84 0 0 0 24 24 17 58 17 \n", + "98 0 0 0 33 35 26 26 0 \n", + "84 0 0 0 39 101 0 0 0 \n", + "\n", + " dura_B6 dura_B7 dura_B8 cycle \n", + "60 0 0 0 140 \n", + "60 0 0 0 140 \n", + "60 0 0 0 140 \n", + "70 0 0 0 120 \n", + "56 0 0 0 150 \n", + ".. ... ... ... ... \n", + "78 0 0 0 150 \n", + "84 0 0 0 140 \n", + "84 0 0 0 140 \n", + "98 0 0 0 120 \n", + "84 0 0 0 140 \n", + "\n", + "[194 rows x 19 columns]" + ] + }, + "execution_count": 55, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "m = 40\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", + "# 1. 조회시점의 유닉스 타임 이전의 신호이력 수집\n", + "rhistory = history.copy() # recent history\n", + "rhistory = rhistory[(rhistory.end_unix < present_time)]\n", + "# 2. 시작 유닉스 타임컬럼 생성 후 종류 유닉스 타임에서 현시별 현시기간 컬럼의 합을 뺀 값으로 입력\n", + "# - 현시시간의 합을 뺀 시간의 +- 10초 이내에 이전 주기정보가 존재하면 그 유닉스 시간을 시작 유닉스시간 값으로 하고, 존재하지 않으면 현시시간의 합을 뺀 유닉스 시간을 시작 유닉스 시간으로 지정\n", + "for i, row in rhistory.iterrows():\n", + " inter_no = row.inter_no\n", + " end_unix = row.end_unix\n", + " elapsed_time = row[[f'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]].sum() // 2 # 현시시간 합\n", + " # 이전 유닉스 존재하지 않음 : 현시시간 합의 차\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", + " # 이전 유닉스 존재, abs < 10 : 이전 유닉스\n", + " if abs(pre_unix - start_unix) < 10:\n", + " start_unix = pre_unix\n", + " # 이전 유닉스 존재, abs >=10 : 현시시간 합의 차\n", + " else:\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", + "rhistory[['inter_no', 'start_unix', 'cycle']][rhistory.inter_no==175]\n", + "rhistory = rhistory[['inter_no', 'start_unix'] + [f'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)] + ['cycle']]\n", + "\n", + "# 2-1. 참값 판단 프로세스\n", + "hours = np.array(range(midnight, next_day + 1, 3600)) # 정각에 해당하는 시각들 목록\n", + "\n", + "def calculate_DS(rhist, curr_unix):\n", + " ghour_lt_curr_unix = hours[hours <= curr_unix].max() # the greatest hour less than (or equal to) curr_unix\n", + " start_unixes = rhist.start_unix.unique()\n", + " start_unixes_lt_ghour = np.sort(start_unixes[start_unixes < ghour_lt_curr_unix]) # start unixes less than ghour_lt_curr_unix\n", + " # 기준유닉스(base_unix) : curr_unix보다 작은 hour 중에서 가장 큰 값으로부터 다섯 번째로 작은 start_unix\n", + " if list(start_unixes_lt_ghour):\n", + " base_unix = start_unixes_lt_ghour[-5]\n", + " # start_unixes_lt_ghour가 비었을 경우에는 맨 앞 start_unix로 base_unix를 지정\n", + " else:\n", + " base_unix = rhist.start_unix.min()\n", + " D_n = curr_unix - base_unix\n", + " S_n_durs = rhist[(rhist.start_unix > base_unix) & (rhist.start_unix <= curr_unix)] \\\n", + " [[f'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]]\n", + " S_n = S_n_durs.values.sum() // 2\n", + " return D_n, S_n\n", + "\n", + "rhists = []\n", + "for inter_no in sorted(rhistory.inter_no.unique()):\n", + " rhist = rhistory.copy()[rhistory.inter_no==inter_no]\n", + " rhist = rhist.drop_duplicates(subset=['start_unix']).reset_index(drop=True)\n", + "\n", + " # D_n 및 S_n 값 정의\n", + " rhist['D_n'] = 0 # D_n : 시간차이\n", + " rhist['S_n'] = 0 # S_n : 현시시간합\n", + " for n in range(len(rhist)):\n", + " curr_unix = rhist.iloc[n].start_unix # current start_unix\n", + " rhist.loc[n, ['D_n', 'S_n']] = calculate_DS(rhist, curr_unix)\n", + "\n", + " # 이전시각, 현재시각\n", + " prev_unix = rhist.loc[0, 'start_unix'] # previous start_unix\n", + " curr_unix = rhist.loc[1, 'start_unix'] # current start_unix\n", + "\n", + " # rhist의 마지막 행에 도달할 때까지 반복\n", + " while True:\n", + " n = rhist[rhist.start_unix==curr_unix].index[0]\n", + " cycle = rhist.loc[n, 'cycle']\n", + " D_n = rhist.loc[n, 'D_n']\n", + " S_n = rhist.loc[n, 'S_n']\n", + " # 참값인 경우\n", + " if (abs(D_n - S_n) <= 5):\n", + " pass\n", + " # 참값이 아닌 경우\n", + " else:\n", + " # 2-1-1. 결측치 처리 : 인접한 두 start_unix의 차이가 계획된 주기의 두 배보다 크면 결측이 일어났다고 판단, 신호계획의 현시시간으로 \"대체\"\n", + " if curr_unix - prev_unix >= 2 * cycle:\n", + " # prev_unix를 계획된 주기만큼 늘려가면서 한 행씩 채워나간다.\n", + " # (curr_unix와의 차이가 계획된 주기보다 작거나 같아질 때까지)\n", + " new_rows = []\n", + " while curr_unix - prev_unix > cycle:\n", + " prev_unix += cycle\n", + " # 신호 계획(prow) 불러오기\n", + " start_seconds = np.array(timetable.start_seconds)\n", + " idx = (start_seconds <= prev_unix).sum() - 1\n", + " start_hour = timetable.iloc[idx].start_hour\n", + " start_minute = timetable.iloc[idx].start_minute\n", + " prow = plan.copy()[(plan.inter_no==inter_no) & (plan.start_hour==start_hour) & (plan.start_minute==start_minute)] # planned row\n", + " # prow에서 필요한 부분을 rhist에 추가\n", + " prow['start_unix'] = prev_unix\n", + " prow = prow.drop(['start_hour', 'start_minute', 'offset'], axis=1)\n", + " cycle = prow.iloc[0].cycle\n", + " rhist = pd.concat([rhist, prow])\n", + " rhist = rhist.sort_values(by='start_unix').reset_index(drop=True)\n", + " n += 1\n", + "\n", + " # 2-1-2. 이상치 처리 : 비율에 따라 해당 행을 \"삭제\"(R_n <= 0.5) 또는 \"조정\"(R_n > 0.5)한다\n", + " R_n = (curr_unix - prev_unix) / cycle # R_n : 비율\n", + " # R_n이 0.5보다 작거나 같으면 해당 행을 삭제\n", + " if R_n <= 0.5:\n", + " rhist = rhist.drop(index=n).reset_index(drop=True)\n", + " # 행삭제에 따른 curr_unix, R_n 재정의\n", + " curr_unix = rhist.loc[n, 'start_unix']\n", + " R_n = (curr_unix - prev_unix) / cycle # R_n : 비율\n", + "\n", + " # R_n이 0.5보다 크면 해당 행 조정 (비율을 유지한 채로 현시시간 대체)\n", + " if R_n > 0.5:\n", + " # 신호 계획(prow) 불러오기\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 = plan[(plan.inter_no==inter_no) & (plan.start_hour==start_hour) & (plan.start_minute==start_minute)] # planned row\n", + " # 조정된 현시시간 (prow에 R_n을 곱하고 정수로 바꿈)\n", + " adjusted_dur = prow.copy()[[f'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]] * R_n\n", + " int_parts = adjusted_dur.iloc[0].apply(lambda x: int(x))\n", + " frac_parts = adjusted_dur.iloc[0] - int_parts\n", + " difference = round(adjusted_dur.iloc[0].sum()) - int_parts.sum()\n", + " for _ in range(difference): # 소수 부분이 가장 큰 상위 '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에 조정된 현시시간을 반영\n", + " rhist.loc[n, [f'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]] = int_parts.values\n", + " rhist.loc[n, 'cycle'] = int_parts.sum().sum() // 2\n", + "\n", + " if n == rhist.index[-1]:\n", + " break\n", + " prev_unix = curr_unix\n", + " curr_unix = rhist.loc[n+1, 'start_unix']\n", + " # rhist['start_dt'] = rhist['start_unix'].map(lambda x:datetime.fromtimestamp(x))\n", + "\n", + " # 생략해도 무방할 코드\n", + " rhist = rhist.reset_index(drop=True)\n", + " rhist = rhist.sort_values(by=['start_unix'])\n", + "\n", + " # D_n 및 S_n 값 재정의\n", + " for n in range(len(rhist)):\n", + " curr_unix = rhist.iloc[n].start_unix # current start_unix\n", + " rhist.loc[n, ['D_n', 'S_n']] = calculate_DS(rhist, curr_unix)\n", + " rhists.append(rhist)\n", + "rhists = pd.concat(rhists).sort_values(by=['start_unix','inter_no'])\n", + "rhists = rhists[rhists.start_unix >= present_time - 3600]\n", + "rhists = rhists.drop(columns=['D_n', 'S_n'])\n", + "rhists" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "metadata": {}, + "outputs": [], + "source": [ + "# file_path = '../../Data/tables/movements/'\n", + "# movements = [pd.read_csv(file_path + file, index_col=0) for file in tqdm(os.listdir(file_path))]\n", + "# movements = pd.concat(movements).drop_duplicates()\n", + "# movements.to_csv(file_path + 'movements.csv')" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "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", + "
inter_nophas_Aphas_Bmove_Amove_B
81751184
151752273
201753361
241753462
261754452
\n", + "
" + ], + "text/plain": [ + " inter_no phas_A phas_B move_A move_B\n", + "8 175 1 1 8 4\n", + "15 175 2 2 7 3\n", + "20 175 3 3 6 1\n", + "24 175 3 4 6 2\n", + "26 175 4 4 5 2" + ] + }, + "execution_count": 57, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "movements = pd.read_csv('../../Data/tables/movements/movements.csv', index_col=0)\n", + "movements_wo_start_unix_list = [] # movements without start_unix\n", + "for inter_no in sorted(movements.inter_no.unique()):\n", + " movements_wo_start_unix = movements[movements.inter_no==inter_no]\n", + " movements_wo_start_unix = movements_wo_start_unix[['inter_no', 'phas_A', 'phas_B', 'move_A', 'move_B']]\n", + " movements_wo_start_unix = movements_wo_start_unix.drop_duplicates().sort_values(by=['phas_A','phas_B'])\n", + " movements_wo_start_unix_list.append(movements_wo_start_unix)\n", + "movements_wo_start_unix = pd.concat(movements_wo_start_unix_list)\n", + "movements_wo_start_unix.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "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_unixphas_Aphas_Bduration
017817043888001138
117817043888002239
217817043888003340
317817043888004423
420117043888001124
..................
76720617043921602235
76820617043921603326
76920617043921604426
77020217043922111139
771202170439221122101
\n", + "

772 rows × 5 columns

\n", + "
" + ], + "text/plain": [ + " inter_no start_unix phas_A phas_B duration\n", + "0 178 1704388800 1 1 38\n", + "1 178 1704388800 2 2 39\n", + "2 178 1704388800 3 3 40\n", + "3 178 1704388800 4 4 23\n", + "4 201 1704388800 1 1 24\n", + ".. ... ... ... ... ...\n", + "767 206 1704392160 2 2 35\n", + "768 206 1704392160 3 3 26\n", + "769 206 1704392160 4 4 26\n", + "770 202 1704392211 1 1 39\n", + "771 202 1704392211 2 2 101\n", + "\n", + "[772 rows x 5 columns]" + ] + }, + "execution_count": 58, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# 계층화된 형태로 변환\n", + "hrhists = [] # hierarchied recent history\n", + "for i, row in rhists.iterrows():\n", + " inter_no = row.inter_no\n", + " start_unix = row.start_unix\n", + "\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", + " phas_As = [isplit[j][0] for j in isplit.keys()]\n", + " phas_Bs = [isplit[j][1] for j in isplit.keys()]\n", + " durs_A = row[[f'dura_A{j}' for j in range(1,9)]]\n", + " durs_B = row[[f'dura_B{j}' for j in range(1,9)]]\n", + " durations = []\n", + " for j in range(1, len(isplit)+1):\n", + " ja = isplit[j][0]\n", + " jb = isplit[j][1]\n", + " if ja == jb:\n", + " durations.append(min(durs_A[ja-1], durs_B[jb-1]))\n", + " else:\n", + " durations.append(abs(durs_A[ja-1] - durs_B[ja-1]))\n", + " new_rows = pd.DataFrame({'inter_no':[inter_no] * len(durations), 'start_unix':[start_unix] * len(durations),\n", + " 'phas_A':phas_As, 'phas_B':phas_Bs, 'duration':durations})\n", + " hrhists.append(new_rows)\n", + "hrhists = pd.concat(hrhists)\n", + "hrhists = hrhists.sort_values(by = ['start_unix', 'inter_no', 'phas_A', 'phas_B']).reset_index(drop=True)\n", + "hrhists" + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "metadata": {}, + "outputs": [], + "source": [ + "movement = pd.read_csv(f'../../Data/tables/movements/movements_{present_time}.csv', index_col=0)" + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "metadata": {}, + "outputs": [], + "source": [ + "# 중복을 제거하고 (inter_no, start_unix) 쌍을 만듭니다.\n", + "hrhists_inter_unix = set(hrhists[['inter_no', 'start_unix']].drop_duplicates().itertuples(index=False, name=None))\n", + "movement_inter_unix = set(movement[['inter_no', 'start_unix']].drop_duplicates().itertuples(index=False, name=None))\n", + "\n", + "# hrhists에는 있지만 movement에는 없는 (inter_no, start_unix) 쌍을 찾습니다.\n", + "missing_in_movement = hrhists_inter_unix - movement_inter_unix\n", + "\n", + "# 새로운 행들을 생성합니다.\n", + "new_rows = []\n", + "for inter_no, start_unix in missing_in_movement:\n", + " # movements_wo_start_unix에서 해당 inter_no의 데이터를 찾습니다.\n", + " new_row = movements_wo_start_unix[movements_wo_start_unix['inter_no'] == inter_no].copy()\n", + " # start_unix 값을 설정합니다.\n", + " new_row['start_unix'] = start_unix\n", + " new_rows.append(new_row)\n", + "\n", + "# 새로운 데이터프레임을 생성하고 기존 movement 데이터프레임과 합칩니다.\n", + "new_movement = pd.concat(new_rows, ignore_index=True)\n", + "movement_updated = pd.concat([movement, new_movement], ignore_index=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "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", + "
inter_nonode_idstart_unixphas_Aphas_Bdurationinc_edge_Aout_edge_Ainc_edge_Bout_edge_B
0177i217043888011136-571542809_01571542811_01571542811_02571542809_01
1177i217043888012220571542811_02571542107_01-571542809_01571542809_01
2177i217043888013368NaNNaNNaNNaN
3177i217043888014426-571542809_01571542811_01571542107_02571542809_01
4176i117043888501137-571542810_01-571542797_02.99571542797_02.99571542810_01
.................................
748206i717043921602235NaNNaNNaNNaN
749206i717043921603326-571511538_02571542073_02571542073_01571511538_02
750206i717043921604426NaNNaNNaNNaN
751202i917043922111139571510152_02-571510152_01571510152_01571510152_01.65
752202i9170439221122101NaNNaNNaNNaN
\n", + "

757 rows × 10 columns

\n", + "
" + ], + "text/plain": [ + " inter_no node_id start_unix phas_A phas_B duration inc_edge_A \\\n", + "0 177 i2 1704388801 1 1 36 -571542809_01 \n", + "1 177 i2 1704388801 2 2 20 571542811_02 \n", + "2 177 i2 1704388801 3 3 68 NaN \n", + "3 177 i2 1704388801 4 4 26 -571542809_01 \n", + "4 176 i1 1704388850 1 1 37 -571542810_01 \n", + ".. ... ... ... ... ... ... ... \n", + "748 206 i7 1704392160 2 2 35 NaN \n", + "749 206 i7 1704392160 3 3 26 -571511538_02 \n", + "750 206 i7 1704392160 4 4 26 NaN \n", + "751 202 i9 1704392211 1 1 39 571510152_02 \n", + "752 202 i9 1704392211 2 2 101 NaN \n", + "\n", + " out_edge_A inc_edge_B out_edge_B \n", + "0 571542811_01 571542811_02 571542809_01 \n", + "1 571542107_01 -571542809_01 571542809_01 \n", + "2 NaN NaN NaN \n", + "3 571542811_01 571542107_02 571542809_01 \n", + "4 -571542797_02.99 571542797_02.99 571542810_01 \n", + ".. ... ... ... \n", + "748 NaN NaN NaN \n", + "749 571542073_02 571542073_01 571511538_02 \n", + "750 NaN NaN NaN \n", + "751 -571510152_01 571510152_01 571510152_01.65 \n", + "752 NaN NaN NaN \n", + "\n", + "[757 rows x 10 columns]" + ] + }, + "execution_count": 61, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "movedur = pd.merge(movement_updated, hrhists, how='inner', on=['inter_no', 'start_unix', 'phas_A', 'phas_B']) # 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", + "\n", + "# 이동류 매칭 테이블에서 진입id, 진출id를 가져와서 붙임.\n", + "for i, row in movedur.iterrows():\n", + " inter_no = row.inter_no\n", + " start_unix = row.start_unix\n", + " # incoming and outgoing edges A\n", + " move_A = row.move_A\n", + " if move_A in [17, 18]:\n", + " inc_edge_A = np.nan\n", + " out_edge_A = np.nan\n", + " else:\n", + " match_A = matching[(matching.inter_no == inter_no) & (matching.move_no == move_A)].iloc[0]\n", + " inc_edge_A = match_A.inc_edge\n", + " out_edge_A = match_A.out_edge\n", + " movedur.loc[i, ['inc_edge_A', 'out_edge_A']] = [inc_edge_A, out_edge_A]\n", + " # incoming and outgoing edges B\n", + " move_B = row.move_B\n", + " if move_B in [17, 18]:\n", + " inc_edge_B = np.nan\n", + " out_edge_B = np.nan\n", + " else:\n", + " match_B = matching[(matching.inter_no == inter_no) & (matching.move_no == move_B)].iloc[0]\n", + " inc_edge_B = match_B.inc_edge\n", + " out_edge_B = match_B.out_edge\n", + " movedur.loc[i, ['inc_edge_B', 'out_edge_B']] = [inc_edge_B, out_edge_B]\n", + "\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", + "histid['node_id'] = histid['inter_no'].map(inter2node)\n", + "histid = histid[['inter_no', 'node_id', 'start_unix', 'phas_A', 'phas_B', 'duration', 'inc_edge_A', 'out_edge_A', 'inc_edge_B', 'out_edge_B']]\n", + "histid = histid[histid.start_unix > present_time - 3600]\n", + "histid" + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2024-01-05 03:20:00\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \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_nonode_idstart_unixphas_Aphas_Bdurationinc_edge_Aout_edge_Ainc_edge_Bout_edge_B
12175i017043888801137-571542797_02571500487_01-571500487_01571542797_02
13175i017043888802239-571500487_01571545870_01-571542797_02571510153_01
14175i017043888803325571545870_02571510153_01571545870_02571542797_02
15175i017043888803430571545870_02571510153_01571510153_02571545870_01
16175i017043888804429571510153_02571500487_01571510153_02571545870_01
44175i017043890401137-571542797_02571500487_01-571500487_01571542797_02
45175i017043890402239-571500487_01571545870_01-571542797_02571510153_01
46175i017043890403325571545870_02571510153_01571545870_02571542797_02
47175i017043890403430571545870_02571510153_01571510153_02571545870_01
48175i017043890404429571510153_02571500487_01571510153_02571545870_01
80175i017043892001137-571542797_02571500487_01-571500487_01571542797_02
81175i017043892002239-571500487_01571545870_01-571542797_02571510153_01
82175i017043892003325571545870_02571510153_01571545870_02571542797_02
83175i017043892003430571545870_02571510153_01571510153_02571545870_01
84175i017043892004429571510153_02571500487_01571510153_02571545870_01
117175i017043893601137-571542797_02571500487_01-571500487_01571542797_02
118175i017043893602239-571500487_01571545870_01-571542797_02571510153_01
119175i017043893603325571545870_02571510153_01571545870_02571542797_02
120175i017043893603430571545870_02571510153_01571510153_02571545870_01
121175i017043893604429571510153_02571500487_01571510153_02571545870_01
155175i017043895201137-571542797_02571500487_01-571500487_01571542797_02
156175i017043895202239-571500487_01571545870_01-571542797_02571510153_01
157175i017043895203325571545870_02571510153_01571545870_02571542797_02
158175i017043895203430571545870_02571510153_01571510153_02571545870_01
159175i017043895204429571510153_02571500487_01571510153_02571545870_01
191175i017043896801137-571542797_02571500487_01-571500487_01571542797_02
192175i017043896802239-571500487_01571545870_01-571542797_02571510153_01
193175i017043896803325571545870_02571510153_01571545870_02571542797_02
194175i017043896803430571545870_02571510153_01571510153_02571545870_01
195175i017043896804429571510153_02571500487_01571510153_02571545870_01
223175i017043898391137-571542797_02571500487_01-571500487_01571542797_02
224175i017043898392239-571500487_01571545870_01-571542797_02571510153_01
225175i017043898393325571545870_02571510153_01571545870_02571542797_02
226175i017043898393430571545870_02571510153_01571510153_02571545870_01
227175i017043898394429571510153_02571500487_01571510153_02571545870_01
255175i017043900001137-571542797_02571500487_01-571500487_01571542797_02
256175i017043900002239-571500487_01571545870_01-571542797_02571510153_01
257175i017043900003325571545870_02571510153_01571545870_02571542797_02
258175i017043900003430571545870_02571510153_01571510153_02571545870_01
259175i017043900004429571510153_02571500487_01571510153_02571545870_01
295175i017043901601137-571542797_02571500487_01-571500487_01571542797_02
296175i017043901602239-571500487_01571545870_01-571542797_02571510153_01
297175i017043901603325571545870_02571510153_01571545870_02571542797_02
298175i017043901603430571545870_02571510153_01571510153_02571545870_01
299175i017043901604429571510153_02571500487_01571510153_02571545870_01
325175i017043903201137-571542797_02571500487_01-571500487_01571542797_02
326175i017043903202239-571500487_01571545870_01-571542797_02571510153_01
327175i017043903203325571545870_02571510153_01571545870_02571542797_02
328175i017043903203430571545870_02571510153_01571510153_02571545870_01
329175i017043903204429571510153_02571500487_01571510153_02571545870_01
355175i017043904801137-571542797_02571500487_01-571500487_01571542797_02
356175i017043904802239-571500487_01571545870_01-571542797_02571510153_01
357175i017043904803325571545870_02571510153_01571545870_02571542797_02
358175i017043904803430571545870_02571510153_01571510153_02571545870_01
359175i017043904804429571510153_02571500487_01571510153_02571545870_01
400175i017043906401137-571542797_02571500487_01-571500487_01571542797_02
401175i017043906402239-571500487_01571545870_01-571542797_02571510153_01
402175i017043906403325571545870_02571510153_01571545870_02571542797_02
403175i017043906403430571545870_02571510153_01571510153_02571545870_01
404175i017043906404429571510153_02571500487_01571510153_02571545870_01
\n", + "
" + ], + "text/plain": [ + " inter_no node_id start_unix phas_A phas_B duration inc_edge_A \\\n", + "12 175 i0 1704388880 1 1 37 -571542797_02 \n", + "13 175 i0 1704388880 2 2 39 -571500487_01 \n", + "14 175 i0 1704388880 3 3 25 571545870_02 \n", + "15 175 i0 1704388880 3 4 30 571545870_02 \n", + "16 175 i0 1704388880 4 4 29 571510153_02 \n", + "44 175 i0 1704389040 1 1 37 -571542797_02 \n", + "45 175 i0 1704389040 2 2 39 -571500487_01 \n", + "46 175 i0 1704389040 3 3 25 571545870_02 \n", + "47 175 i0 1704389040 3 4 30 571545870_02 \n", + "48 175 i0 1704389040 4 4 29 571510153_02 \n", + "80 175 i0 1704389200 1 1 37 -571542797_02 \n", + "81 175 i0 1704389200 2 2 39 -571500487_01 \n", + "82 175 i0 1704389200 3 3 25 571545870_02 \n", + "83 175 i0 1704389200 3 4 30 571545870_02 \n", + "84 175 i0 1704389200 4 4 29 571510153_02 \n", + "117 175 i0 1704389360 1 1 37 -571542797_02 \n", + "118 175 i0 1704389360 2 2 39 -571500487_01 \n", + "119 175 i0 1704389360 3 3 25 571545870_02 \n", + "120 175 i0 1704389360 3 4 30 571545870_02 \n", + "121 175 i0 1704389360 4 4 29 571510153_02 \n", + "155 175 i0 1704389520 1 1 37 -571542797_02 \n", + "156 175 i0 1704389520 2 2 39 -571500487_01 \n", + "157 175 i0 1704389520 3 3 25 571545870_02 \n", + "158 175 i0 1704389520 3 4 30 571545870_02 \n", + "159 175 i0 1704389520 4 4 29 571510153_02 \n", + "191 175 i0 1704389680 1 1 37 -571542797_02 \n", + "192 175 i0 1704389680 2 2 39 -571500487_01 \n", + "193 175 i0 1704389680 3 3 25 571545870_02 \n", + "194 175 i0 1704389680 3 4 30 571545870_02 \n", + "195 175 i0 1704389680 4 4 29 571510153_02 \n", + "223 175 i0 1704389839 1 1 37 -571542797_02 \n", + "224 175 i0 1704389839 2 2 39 -571500487_01 \n", + "225 175 i0 1704389839 3 3 25 571545870_02 \n", + "226 175 i0 1704389839 3 4 30 571545870_02 \n", + "227 175 i0 1704389839 4 4 29 571510153_02 \n", + "255 175 i0 1704390000 1 1 37 -571542797_02 \n", + "256 175 i0 1704390000 2 2 39 -571500487_01 \n", + "257 175 i0 1704390000 3 3 25 571545870_02 \n", + "258 175 i0 1704390000 3 4 30 571545870_02 \n", + "259 175 i0 1704390000 4 4 29 571510153_02 \n", + "295 175 i0 1704390160 1 1 37 -571542797_02 \n", + "296 175 i0 1704390160 2 2 39 -571500487_01 \n", + "297 175 i0 1704390160 3 3 25 571545870_02 \n", + "298 175 i0 1704390160 3 4 30 571545870_02 \n", + "299 175 i0 1704390160 4 4 29 571510153_02 \n", + "325 175 i0 1704390320 1 1 37 -571542797_02 \n", + "326 175 i0 1704390320 2 2 39 -571500487_01 \n", + "327 175 i0 1704390320 3 3 25 571545870_02 \n", + "328 175 i0 1704390320 3 4 30 571545870_02 \n", + "329 175 i0 1704390320 4 4 29 571510153_02 \n", + "355 175 i0 1704390480 1 1 37 -571542797_02 \n", + "356 175 i0 1704390480 2 2 39 -571500487_01 \n", + "357 175 i0 1704390480 3 3 25 571545870_02 \n", + "358 175 i0 1704390480 3 4 30 571545870_02 \n", + "359 175 i0 1704390480 4 4 29 571510153_02 \n", + "400 175 i0 1704390640 1 1 37 -571542797_02 \n", + "401 175 i0 1704390640 2 2 39 -571500487_01 \n", + "402 175 i0 1704390640 3 3 25 571545870_02 \n", + "403 175 i0 1704390640 3 4 30 571545870_02 \n", + "404 175 i0 1704390640 4 4 29 571510153_02 \n", + "\n", + " out_edge_A inc_edge_B out_edge_B \n", + "12 571500487_01 -571500487_01 571542797_02 \n", + "13 571545870_01 -571542797_02 571510153_01 \n", + "14 571510153_01 571545870_02 571542797_02 \n", + "15 571510153_01 571510153_02 571545870_01 \n", + "16 571500487_01 571510153_02 571545870_01 \n", + "44 571500487_01 -571500487_01 571542797_02 \n", + "45 571545870_01 -571542797_02 571510153_01 \n", + "46 571510153_01 571545870_02 571542797_02 \n", + "47 571510153_01 571510153_02 571545870_01 \n", + "48 571500487_01 571510153_02 571545870_01 \n", + "80 571500487_01 -571500487_01 571542797_02 \n", + "81 571545870_01 -571542797_02 571510153_01 \n", + "82 571510153_01 571545870_02 571542797_02 \n", + "83 571510153_01 571510153_02 571545870_01 \n", + "84 571500487_01 571510153_02 571545870_01 \n", + "117 571500487_01 -571500487_01 571542797_02 \n", + "118 571545870_01 -571542797_02 571510153_01 \n", + "119 571510153_01 571545870_02 571542797_02 \n", + "120 571510153_01 571510153_02 571545870_01 \n", + "121 571500487_01 571510153_02 571545870_01 \n", + "155 571500487_01 -571500487_01 571542797_02 \n", + "156 571545870_01 -571542797_02 571510153_01 \n", + "157 571510153_01 571545870_02 571542797_02 \n", + "158 571510153_01 571510153_02 571545870_01 \n", + "159 571500487_01 571510153_02 571545870_01 \n", + "191 571500487_01 -571500487_01 571542797_02 \n", + "192 571545870_01 -571542797_02 571510153_01 \n", + "193 571510153_01 571545870_02 571542797_02 \n", + "194 571510153_01 571510153_02 571545870_01 \n", + "195 571500487_01 571510153_02 571545870_01 \n", + "223 571500487_01 -571500487_01 571542797_02 \n", + "224 571545870_01 -571542797_02 571510153_01 \n", + "225 571510153_01 571545870_02 571542797_02 \n", + "226 571510153_01 571510153_02 571545870_01 \n", + "227 571500487_01 571510153_02 571545870_01 \n", + "255 571500487_01 -571500487_01 571542797_02 \n", + "256 571545870_01 -571542797_02 571510153_01 \n", + "257 571510153_01 571545870_02 571542797_02 \n", + "258 571510153_01 571510153_02 571545870_01 \n", + "259 571500487_01 571510153_02 571545870_01 \n", + "295 571500487_01 -571500487_01 571542797_02 \n", + "296 571545870_01 -571542797_02 571510153_01 \n", + "297 571510153_01 571545870_02 571542797_02 \n", + "298 571510153_01 571510153_02 571545870_01 \n", + "299 571500487_01 571510153_02 571545870_01 \n", + "325 571500487_01 -571500487_01 571542797_02 \n", + "326 571545870_01 -571542797_02 571510153_01 \n", + "327 571510153_01 571545870_02 571542797_02 \n", + "328 571510153_01 571510153_02 571545870_01 \n", + "329 571500487_01 571510153_02 571545870_01 \n", + "355 571500487_01 -571500487_01 571542797_02 \n", + "356 571545870_01 -571542797_02 571510153_01 \n", + "357 571510153_01 571545870_02 571542797_02 \n", + "358 571510153_01 571510153_02 571545870_01 \n", + "359 571500487_01 571510153_02 571545870_01 \n", + "400 571500487_01 -571500487_01 571542797_02 \n", + "401 571545870_01 -571542797_02 571510153_01 \n", + "402 571510153_01 571545870_02 571542797_02 \n", + "403 571510153_01 571510153_02 571545870_01 \n", + "404 571500487_01 571510153_02 571545870_01 " + ] + }, + "execution_count": 69, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print(datetime.fromtimestamp(present_time))\n", + "histid[histid.inter_no==175][:60]" + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "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", + "
inter_nostart_hourstart_minutedura_A1dura_A2dura_A3dura_A4dura_A5dura_A6dura_A7...dura_B1dura_B2dura_B3dura_B4dura_B5dura_B6dura_B7dura_B8cycleoffset
01750037395529000...37392559000016057
11757040425533000...40422959000017040
21759043455537000...43453359000018028
3175183046485541000...46483759000019018
\n", + "

4 rows × 21 columns

\n", + "
" + ], + "text/plain": [ + " inter_no start_hour start_minute dura_A1 dura_A2 dura_A3 dura_A4 \\\n", + "0 175 0 0 37 39 55 29 \n", + "1 175 7 0 40 42 55 33 \n", + "2 175 9 0 43 45 55 37 \n", + "3 175 18 30 46 48 55 41 \n", + "\n", + " dura_A5 dura_A6 dura_A7 ... dura_B1 dura_B2 dura_B3 dura_B4 \\\n", + "0 0 0 0 ... 37 39 25 59 \n", + "1 0 0 0 ... 40 42 29 59 \n", + "2 0 0 0 ... 43 45 33 59 \n", + "3 0 0 0 ... 46 48 37 59 \n", + "\n", + " dura_B5 dura_B6 dura_B7 dura_B8 cycle offset \n", + "0 0 0 0 0 160 57 \n", + "1 0 0 0 0 170 40 \n", + "2 0 0 0 0 180 28 \n", + "3 0 0 0 0 190 18 \n", + "\n", + "[4 rows x 21 columns]" + ] + }, + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \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_unixdura_A1dura_A2dura_A3dura_A4dura_A5dura_A6dura_A7dura_A8dura_B1dura_B2dura_B3dura_B4dura_B5dura_B6dura_B7dura_B8cycleoffset
6175170438056137395529000037392559000016057
14175170438072037395529000037392559000016057
22175170438088137395529000037392559000016057
31175170438104037395529000037392559000016057
39175170438120037395529000037392559000016057
...............................................................
3844175170446601046485541000046483759000019018
3852175170446620046485541000046483759000019018
3860175170446639046485541000046483759000019018
3868175170446658046485541000046483759000019018
3876175170446676946485541000046483759000019018
\n", + "

496 rows × 20 columns

\n", + "
" + ], + "text/plain": [ + " inter_no end_unix dura_A1 dura_A2 dura_A3 dura_A4 dura_A5 \\\n", + "6 175 1704380561 37 39 55 29 0 \n", + "14 175 1704380720 37 39 55 29 0 \n", + "22 175 1704380881 37 39 55 29 0 \n", + "31 175 1704381040 37 39 55 29 0 \n", + "39 175 1704381200 37 39 55 29 0 \n", + "... ... ... ... ... ... ... ... \n", + "3844 175 1704466010 46 48 55 41 0 \n", + "3852 175 1704466200 46 48 55 41 0 \n", + "3860 175 1704466390 46 48 55 41 0 \n", + "3868 175 1704466580 46 48 55 41 0 \n", + "3876 175 1704466769 46 48 55 41 0 \n", + "\n", + " dura_A6 dura_A7 dura_A8 dura_B1 dura_B2 dura_B3 dura_B4 dura_B5 \\\n", + "6 0 0 0 37 39 25 59 0 \n", + "14 0 0 0 37 39 25 59 0 \n", + "22 0 0 0 37 39 25 59 0 \n", + "31 0 0 0 37 39 25 59 0 \n", + "39 0 0 0 37 39 25 59 0 \n", + "... ... ... ... ... ... ... ... ... \n", + "3844 0 0 0 46 48 37 59 0 \n", + "3852 0 0 0 46 48 37 59 0 \n", + "3860 0 0 0 46 48 37 59 0 \n", + "3868 0 0 0 46 48 37 59 0 \n", + "3876 0 0 0 46 48 37 59 0 \n", + "\n", + " dura_B6 dura_B7 dura_B8 cycle offset \n", + "6 0 0 0 160 57 \n", + "14 0 0 0 160 57 \n", + "22 0 0 0 160 57 \n", + "31 0 0 0 160 57 \n", + "39 0 0 0 160 57 \n", + "... ... ... ... ... ... \n", + "3844 0 0 0 190 18 \n", + "3852 0 0 0 190 18 \n", + "3860 0 0 0 190 18 \n", + "3868 0 0 0 190 18 \n", + "3876 0 0 0 190 18 \n", + "\n", + "[496 rows x 20 columns]" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "display(plan[plan.inter_no==175])\n", + "display(history[history.inter_no==175])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "for m in range(30, 288):\n", + " print(m)\n", + " make_histid(m).to_csv(f'../../Data/tables/histids/histids_{fmins[m]}.csv')" + ] + } + ], + "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 +} diff --git a/Analysis/0109_preprocess/0122_preprocess_9.7.ipynb b/Analysis/0109_preprocess/0122_preprocess_9.7.ipynb new file mode 100644 index 000000000..b2236f2f2 --- /dev/null +++ b/Analysis/0109_preprocess/0122_preprocess_9.7.ipynb @@ -0,0 +1,1459 @@ +{ + "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": [], + "source": [ + "def make_match1():\n", + " '''\n", + " 설명 :\n", + " 신호 DB에는 매 초마다 이동류정보가 업데이트 된다. 그리고 이 이동류정보를 매 5초마다 불러와서 사용하게 된다.\n", + " '../../Data/tables/moves/'에는 5초마다의 이동류정보가 저장되어 있다.\n", + "\n", + " return : 통합된 이동류정보\n", + " - 모든 inter_no(교차로번호)에 대한 A, B링 현시별 이동류정보\n", + " '''\n", + " # [이동류번호] 불러오기 (약 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.to_csv(path_moves + \"match1.csv\")\n", + " return match1" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "def make_match2(match1):\n", + " '''\n", + " match1을 계층화함.\n", + " - match1의 컬럼 : inter_no, phas_A, phas_B, move_A, move_B\n", + " - match2의 컬럼 : inter_no, phase_no, ring_type, move_no\n", + " '''\n", + " # 계층화 (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", + " return match2" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "def make_match3(match2):\n", + " '''\n", + " 각 movement들에 방향(진입방향, 진출방향)을 매칭시켜 추가함.\n", + " - match2의 컬럼 : inter_no, phase_no, ring_type, move_no\n", + " - match3의 컬럼 : inter_no, phase_no, ring_type, move_no, inc_dir, out_dir\n", + "\n", + " nema : \n", + " - 컬럼 : move_no, inc_dir, out_dir\n", + " - 모든 종류의 이동류번호에 대하여 진입방향과 진출방향을 매칭시키는 테이블\n", + " - 이동류번호 : 1 ~ 16, 17, 18, 21\n", + " - 진입, 진출방향(8방위) : 동, 서, 남, 북, 북동, 북서, 남동, 남서\n", + " '''\n", + " # 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", + " return match3" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "def make_match4(match3):\n", + " '''\n", + " 방위각 정보를 매칭시켜 추가함.\n", + " - match3의 컬럼 : inter_no, phase_no, ring_type, move_no, inc_dir, out_dir\n", + " - match4의 컬럼 : inter_no, phase_no, ring_type, move_no, inc_dir, out_dir, inc_angle, out_angle\n", + "\n", + " angle_original : \n", + " - 컬럼 : inter_no, angle_Aj, angle_Bj (j : 1 ~ 8)\n", + " - 모든 종류의 이동류번호에 대하여 진입방향과 진출방향을 매칭시키는 테이블\n", + " - 이동류번호 : 1 ~ 16, 17, 18, 21\n", + " - 진입, 진출방향(8방위) : 동, 서, 남, 북, 북동, 북서, 남동, 남서\n", + " '''\n", + "\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", + " # 계층화\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", + " # 병합\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", + " return match4" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "def make_match5(match4):\n", + " '''\n", + " 진입엣지id, 진출엣지id, 노드id를 추가함 (주교차로).\n", + " - match4의 컬럼 : inter_no, phase_no, ring_type, move_no, inc_dir, out_dir, inc_angle, out_angle\n", + " - match5의 컬럼 : inter_no, phase_no, ring_type, move_no, inc_dir, out_dir, inc_angle, out_angle, inc_edge, out_edge, node_id\n", + " \n", + " 사용된 데이터 : \n", + " (1) net\n", + " - 성남시 정자동 부근의 샘플 네트워크\n", + " (2) inter_node\n", + " - 교차로번호와 노드id를 매칭시키는 테이블.\n", + " - parent/child 정보도 포함되어 있음\n", + " - 컬럼 : inter_no, node_id, inter_type\n", + " (3) inter_info\n", + " - 교차로 정보. 여기에서는 위도와 경도가 쓰임.\n", + " - 컬럼 : inter_no, inter_name, inter_lat, inter_lon, group_no, main_phase_no\n", + "\n", + " 진입엣지id, 진출엣지id를 얻는 과정 :\n", + " - match5 = match4.copy()의 각 열을 순회하면서 아래 과정을 반복함.\n", + " * 진입에 대해서만 서술하겠지만 진출도 마찬가지로 설명될 수 있음\n", + " - 해당 행의 교차로정보로부터 노드ID를 얻어내고, 해당 노드에 대한 모든 진출엣지id를 inc_edges에 저장.\n", + " * inc_edge(진입엣지) : incoming edge, out_edge(진출엣지) : outgoing_edge\n", + " - inc_edges의 모든 진입엣지에 대하여 진입방향(inc_dires, 2차원 단위벡터)을 얻어냄.\n", + " - 해당 행의 진입각으로부터 그에 대응되는 진입각방향(단위벡터)를 얻어냄.\n", + " - 주어진 진입각방향에 대하여 내적이 가장 작은 진입방향에 대한 진입엣지를 inc_edge_id로 지정함.\n", + " '''\n", + "\n", + " # 네트워크 불러오기 \n", + " net = sumolib.net.readNet('../../Data/networks/SN_sample.net.xml')\n", + " # 교차로-노드 매칭 정보 불러오기\n", + " inter_node = pd.read_csv('../../Data/tables/inter_node.csv', index_col=0)\n", + " # 교차로정보(위, 경도) 불러오기\n", + " inter_info = pd.read_csv('../../Data/tables/inter_info.csv', index_col=0)\n", + "\n", + " # parent node만 가져옴.\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.sort_values(by=['inter_no','phase_no','ring_type']).reset_index(drop=True)\n", + " return match5" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "def make_match6(match5):\n", + " '''\n", + " 진입엣지id, 진출엣지id, 노드id를 추가함 (부교차로).\n", + " - match6의 컬럼 : inter_no, phase_no, ring_type, move_no, inc_dir, out_dir, inc_angle, out_angle, inc_edge, out_edge, node_id\n", + " \n", + " 사용된 데이터 : \n", + " (1) inter_node\n", + " - 교차로번호와 노드id를 매칭시키는 테이블.\n", + " - parent/child 정보도 포함되어 있음\n", + " - 컬럼 : inter_no, node_id, inter_type\n", + " (2) uturn (유턴정보)\n", + " - 컬럼 : parent_id, child_id, direction, condition, inc_edge, out_edge\n", + " - parent_id, child_id : 주교차로id, 유턴교차로id\n", + " - direction : 주교차로에 대한 유턴노드의 상대적인 위치(방향)\n", + " - condition : 좌회전시, 직진시, 직좌시, 보행신호시 중 하나\n", + " - inc_edge, out_edge : 유턴에 대한 진입진출엣지\n", + " (3) coord (연동교차로정보)\n", + " - 컬럼 : parent_id, child_id, phase_no, ring_type, inc_edge, out_edge\n", + " - parent_id, child_id : 주교차로id, 연동교차로id\n", + " - 나머지 컬럼 : 각 (현시, 링)별 진입진출엣지\n", + "\n", + " 설명 :\n", + " - match5는 주교차로에 대해서만 진입엣지id, 진출엣지id, 노드id를 추가했었음.\n", + " 여기에서 uturn, coord를 사용해서 부교차로들(유턴교차로, 연동교차로)에 대해서도 해당 값들을 부여함.\n", + " 유턴교차로 :\n", + " - directions를 정북기준 시계방향의 8방위로 정함.\n", + " - 이를 통해 진입방향이 주어진 경우에 좌회전, 직진, 보행 등에 대한 (진입방향, 진출방향)을 얻어낼 수 있음.\n", + " - 예) 진입방향(direction)이 '북'일 때, \n", + " - 직진 : (북, 남)\n", + " * 남 : directions[(ind + 4) % len(directions)]\n", + " - 좌회전 : (북, 동)\n", + " * 동 : directions[(ind + 2) % len(directions)]\n", + " - 보행 : (서, 동)\n", + " * 서 : directions[(ind - 2) % len(directions)]\n", + " - uturn의 각 행을 순회하면서 아래 과정을 반복함\n", + " - match5에서 parent_id에 해당하는 행들을 가져옴(cmatch).\n", + " - condition 별로 진입방향, 진출방향A, 진출방향B 정함.\n", + " - 상술한 directions를 활용하여 정함.\n", + " - (진입방향, 진출방향A, 진출방향B)을 고려하여 (현시, 링) 별로 진입엣지id, 진출엣지id를 정함.\n", + " - ex) cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_A), ['inc_edge', 'out_edge']] = [inc_edge_id, out_edge_id]\n", + " - 순회하면서 만든 cmatch를 cmatchs라는 리스트에 저장함.\n", + "\n", + " 연동교차로 :\n", + " - 연동교차로의 경우 coord에 (현시, 링)별 진입엣지ID, 진출엣지ID가 명시되어 있음.\n", + " - 'inc_dir', 'out_dir', 'inc_angle','out_angle'와 같은 열들은 np.nan을 지정해놓음.\n", + " - 이 열들은, 사실상 다음 스텝부터는 사용되지 않는 열들이기 때문에 np.nan으로 지정해놓아도 문제없음.\n", + "\n", + " match6 :\n", + " - 이렇게 얻은 match5, cmatchs, coord를 모두 pd.concat하여 match6을 얻어냄.\n", + " '''\n", + "\n", + " inter_node = pd.read_csv('../../Data/tables/inter_node.csv', index_col=0)\n", + " node2inter = dict(zip(inter_node['node_id'], inter_node['inter_no']))\n", + "\n", + " uturn = pd.read_csv('../../Data/tables/child_uturn.csv')\n", + " coord = pd.read_csv('../../Data/tables/child_coord.csv')\n", + " child_ids = inter_node[inter_node.inter_type=='child'].node_id.unique()\n", + " ch2pa = {} # child to parent\n", + " for child_id in child_ids:\n", + " parent_no = inter_node[inter_node.node_id==child_id].inter_no.iloc[0]\n", + " sub_inter_node = inter_node[inter_node.inter_no==parent_no]\n", + " ch2pa[child_id] = sub_inter_node[sub_inter_node.inter_type=='parent'].iloc[0].node_id\n", + " directions = ['북', '북동', '동', '남동', '남', '남서', '서', '북서'] # 정북기준 시계방향으로 8방향\n", + "\n", + " # 각 uturn node에 대하여 (inc_edge_id, out_edge_id) 부여\n", + " cmatches = []\n", + " for _, row in uturn.iterrows():\n", + " child_id = row.child_id\n", + " parent_id = row.parent_id\n", + " direction = row.direction\n", + " condition = row.condition\n", + " inc_edge_id = row.inc_edge\n", + " out_edge_id = row.out_edge\n", + " # match5에서 parent_id에 해당하는 행들을 가져옴\n", + " cmatch = match5.copy()[match5.node_id==parent_id] # match dataframe for a child node\n", + " cmatch = cmatch.sort_values(by=['phase_no', 'ring_type']).reset_index(drop=True)\n", + " cmatch['node_id'] = child_id\n", + " cmatch[['inc_edge', 'out_edge']] = np.nan\n", + "\n", + " # condition 별로 inc_dire, out_dire_A, out_dire_B를 정함\n", + " ind = directions.index(direction)\n", + " if condition == \"좌회전시\":\n", + " inc_dire = direction\n", + " out_dire_A = out_dire_B = directions[(ind + 2) % len(directions)]\n", + " elif condition == \"직진시\":\n", + " inc_dire = direction\n", + " out_dire_A = out_dire_B = directions[(ind + 4) % len(directions)]\n", + " elif condition == \"직좌시\":\n", + " inc_dire = direction\n", + " out_dire_A = directions[(ind + 2) % len(directions)]\n", + " out_dire_B = directions[(ind + 4) % len(directions)]\n", + " elif condition == \"보행신호시\":\n", + " inc_dire = directions[(ind + 2) % len(directions)]\n", + " out_dire_A = directions[(ind - 2) % len(directions)]\n", + " out_dire_B = directions[(ind - 2) % len(directions)]\n", + "\n", + " # (inc_dire, out_dire_A, out_dire_B) 별로 inc_edge_id, out_edge_id를 정함\n", + " if condition == '직좌시':\n", + " ap = cmatch[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_A)].phase_no.iloc[0]\n", + " bp = cmatch[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_B)].phase_no.iloc[0]\n", + " # 직진과 좌회전이 같은 현시에 있는 경우에만 (inc_edge_id, out_edge_id)를 부여한다.\n", + " if ap == bp:\n", + " cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_A), ['inc_edge', 'out_edge']] = [inc_edge_id, out_edge_id]\n", + " cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_B), ['inc_edge', 'out_edge']] = [inc_edge_id, out_edge_id]\n", + " elif condition == '보행신호시':\n", + " cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_A), ['inc_edge', 'out_edge']] = [inc_edge_id, out_edge_id]\n", + " cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_B), ['inc_edge', 'out_edge']] = [inc_edge_id, out_edge_id]\n", + " # 이동류번호가 17(보행신호)이면서 유턴노드방향으로 가는 신호가 없으면 (inc_edge_id, out_edge_id)를 부여한다.\n", + " cmatch.loc[(cmatch.move_no==17) & (cmatch.out_dir!=direction), ['inc_edge', 'out_edge']] = [inc_edge_id, out_edge_id]\n", + " else: # '직진시', '좌회전시'\n", + " cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_A), ['inc_edge', 'out_edge']] = [inc_edge_id, out_edge_id]\n", + " cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_B), ['inc_edge', 'out_edge']] = [inc_edge_id, out_edge_id]\n", + " # 유턴신호의 이동류번호를 19로 부여한다.\n", + " cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_A), 'move_no'] = 19\n", + " cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_B), 'move_no'] = 19\n", + " cmatches.append(cmatch)\n", + "\n", + " # 각 coordination node에 대하여 (inc_edge_id, out_edge_id) 부여\n", + " coord['inter_no'] = coord['parent_id'].map(node2inter)\n", + " coord = coord.rename(columns={'child_id':'node_id'})\n", + " coord[['inc_dir', 'out_dir', 'inc_angle','out_angle']] = np.nan\n", + " coord['move_no'] = 20\n", + " coord = coord[['inter_no', 'phase_no', 'ring_type', 'move_no', 'inc_dir', 'out_dir', 'inc_angle','out_angle', 'inc_edge', 'out_edge', 'node_id']]\n", + " \n", + " # display(coord)\n", + " cmatches = pd.concat(cmatches)\n", + " match6 = pd.concat([match5, cmatches, coord]).drop_duplicates().sort_values(by=['inter_no', 'node_id', 'phase_no', 'ring_type'])\n", + " # with pd.option_context('display.max_rows', None, 'display.max_columns', None):\n", + " match6.to_csv('../../Data/tables/matching/match6.csv')\n", + " return match6" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "def make_matching(match6):\n", + " '''\n", + " 이동류 매칭 : 각 교차로에 대하여, 가능한 모든 이동류 (1~18, 21)에 대한 진입·진출엣지ID를 지정한다.\n", + " 모든 이동류에 대해 지정하므로, 시차제시 이전과 다른 이동류가 등장하더라도 항상 진입·진출 엣지 ID를 지정할 수 있다. \n", + " - matching의 컬럼 : inter_no, move_no, inc_dir, out_dir, inc_edge, out_edge, node_id\n", + " \n", + " 설명 : \n", + " - 필요한 리스트, 딕셔너리 등을 정의\n", + " (1) 가능한 (진입방향, 진출방향) 목록 [리스트]\n", + " (2) 각 교차로별 방향 목록 : pdires (possible directions) [딕셔너리]\n", + " (3) 각 (교차로, 진입방향) 별 진입id 목록 : inc2id (incoming direction to incoming edge_id) [딕셔너리]\n", + " (4) 각 (교차로, 진출방향) 별 진출id 목록 : out2id (outgoing direction to outgoing edge_id) [딕셔너리]\n", + " (5) 각 교차로별 가능한 (진입방향, 진출방향) 목록 : pflow (possible flows) [딕셔너리]\n", + " - matching은 빈 리스트로 지정.\n", + " - 모든 노드id에 대하여 다음 과정을 반복\n", + " - 해당 노드id에 대한 모든 가능한 (진입방향, 진출방향)에 대하여 다음 과정을 반복\n", + " - (노드id, 진입방향)으로부터 진입엣지id를 얻어냄. 마찬가지로 진출엣지id도 얻어냄\n", + " - 얻어낸 정보를 바탕으로 한 행(new_row)을 만들고 이것을 matching에 append\n", + " '''\n", + "\n", + " match7 = match6.copy()\n", + " match7 = match7[['inter_no', 'move_no', 'inc_dir', 'out_dir', 'inc_edge', 'out_edge', 'node_id']]\n", + " inter_node = pd.read_csv('../../Data/tables/inter_node.csv', index_col=0)\n", + " nema = pd.read_csv('../../Data/tables/nema.csv', encoding='cp949')\n", + "\n", + " parent_ids = sorted(inter_node[inter_node.inter_type=='parent'].node_id.unique())\n", + " child_ids = sorted(inter_node[inter_node.inter_type=='child'].node_id.unique())\n", + "\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 node_id in parent_ids:\n", + " dires = match7[match7.node_id == node_id][['inc_dir','out_dir']].values.flatten()\n", + " dires = {dire for dire in dires if type(dire)==str}\n", + " pdires[node_id] = dires\n", + " # (3) 각 (교차로, 진입방향) 별 진입id 목록 : inc2id (incoming direction to incoming edge_id)\n", + " inc2id = {}\n", + " for node_id in parent_ids:\n", + " for inc_dir in pdires[node_id]:\n", + " df = match7[(match7.node_id==node_id) & (match7.inc_dir==inc_dir)]\n", + " inc2id[(node_id, inc_dir)] = df.inc_edge.iloc[0]\n", + " # (4) 각 (교차로, 진출방향) 별 진출id 목록 : out2id (outgoing direction to outgoing edge_id)\n", + " out2id = {}\n", + " for node_id in parent_ids:\n", + " for out_dir in pdires[node_id]:\n", + " df = match7[(match7.node_id==node_id) & (match7.out_dir==out_dir)]\n", + " out2id[(node_id, out_dir)] = df.out_edge.iloc[0]\n", + " # (5) 각 교차로별 가능한 (진입방향, 진출방향) 목록 : pflow (possible flows)\n", + " pflow = {}\n", + " for node_id in parent_ids:\n", + " pflow[node_id] = [flow for flow in flows if set(flow).issubset(pdires[node_id])]\n", + " # (6) 가능한 이동류에 대하여 진입id, 진출id 배정 : matching\n", + " node2inter = dict(zip(match7['node_id'], match7['inter_no']))\n", + " dires_right = ['북', '서', '남', '동', '북'] # ex (북, 서), (서, 남) 등은 우회전 flow\n", + " matching = []\n", + " for node_id in parent_ids:\n", + " inter_no = node2inter[node_id]\n", + " # 좌회전과 직진(1 ~ 16)\n", + " for (inc_dir, out_dir) in pflow[node_id]:\n", + " move_no = nema[(nema.inc_dir==inc_dir) & (nema.out_dir==out_dir)].move_no.iloc[0]\n", + " inc_edge = inc2id[(node_id, inc_dir)]\n", + " out_edge = out2id[(node_id, 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[node_id]):\n", + " inc_edge = inc2id[(node_id, inc_dir)]\n", + " out_edge = out2id[(node_id, 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.append(match7[match7.node_id.isin(child_ids)])\n", + " matching = pd.concat(matching)\n", + " matching = matching.dropna().sort_values(by=['inter_no', 'node_id', 'move_no']).reset_index(drop=True)\n", + " matching['move_no'] = matching['move_no'].astype(int)\n", + " matching.to_csv('../../Data/tables/matching/matching.csv')\n", + " return matching" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "def matching_main():\n", + " match1 = pd.read_csv('../../Data/tables/moves/match1.csv', index_col=0)\n", + " match2 = make_match2(match1)\n", + " match3 = make_match3(match2)\n", + " match4 = make_match4(match3)\n", + " match5 = make_match5(match4)\n", + " match6 = make_match6(match5)\n", + " matching = make_matching(match6)\n", + " return matching\n", + "matching = matching_main()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# B. 5초 간격으로 이동류번호 수집" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "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" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "def save_movement():\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')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# C. 5분 간격으로 신호이력 수집 및 통합테이블 생성" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "midnight = int(datetime(2024, 1, 5, 0, 0, 0).timestamp())\n", + "next_day = int(datetime(2024, 1, 6, 0, 0, 0).timestamp())\n", + "fmins = range(midnight, next_day, 300) # fmins : unix time by Five MINuteS" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [], + "source": [ + "def make_splits(plan):\n", + " # 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", + " return splits, isplits\n", + "\n", + "def make_timetable(plan):\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", + " return timetable\n", + "\n", + "# inter2node\n", + "inter_node = pd.read_csv('../../Data/tables/inter_node.csv', index_col=0)\n", + "inter2node = dict(zip(inter_node['inter_no'], inter_node['node_id']))" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "def make_rhists(present_time, timetable, plan, history):\n", + " # 1. 조회시점의 유닉스 타임 이전의 신호이력 수집\n", + " rhistory = history.copy() # recent history\n", + " rhistory = rhistory[(rhistory.end_unix < present_time)]\n", + " # 2. 시작 유닉스 타임컬럼 생성 후 종류 유닉스 타임에서 현시별 현시기간 컬럼의 합을 뺀 값으로 입력\n", + " # - 현시시간의 합을 뺀 시간의 +- 10초 이내에 이전 주기정보가 존재하면 그 유닉스 시간을 시작 유닉스시간 값으로 하고, 존재하지 않으면 현시시간의 합을 뺀 유닉스 시간을 시작 유닉스 시간으로 지정\n", + " for i, row in rhistory.iterrows():\n", + " inter_no = row.inter_no\n", + " end_unix = row.end_unix\n", + " elapsed_time = row[[f'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]].sum() // 2 # 현시시간 합\n", + " # 이전 유닉스 존재하지 않음 : 현시시간 합의 차\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", + " # 이전 유닉스 존재, abs < 10 : 이전 유닉스\n", + " if abs(pre_unix - start_unix) < 10:\n", + " start_unix = pre_unix\n", + " # 이전 유닉스 존재, abs >=10 : 현시시간 합의 차\n", + " else:\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", + " rhistory[['inter_no', 'start_unix', 'cycle']][rhistory.inter_no==175]\n", + " rhistory = rhistory[['inter_no', 'start_unix'] + [f'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)] + ['cycle']]\n", + "\n", + " # 2-1. 참값 판단 프로세스\n", + " hours = np.array(range(midnight, next_day + 1, 3600)) # 정각에 해당하는 시각들 목록\n", + "\n", + " def calculate_DS(rhist, curr_unix):\n", + " ghour_lt_curr_unix = hours[hours <= curr_unix].max() # the greatest hour less than (or equal to) curr_unix\n", + " start_unixes = rhist.start_unix.unique()\n", + " start_unixes_lt_ghour = np.sort(start_unixes[start_unixes < ghour_lt_curr_unix]) # start unixes less than ghour_lt_curr_unix\n", + " # 기준유닉스(base_unix) : curr_unix보다 작은 hour 중에서 가장 큰 값으로부터 다섯 번째로 작은 start_unix\n", + " if list(start_unixes_lt_ghour):\n", + " base_unix = start_unixes_lt_ghour[-5]\n", + " # start_unixes_lt_ghour가 비었을 경우에는 맨 앞 start_unix로 base_unix를 지정\n", + " else:\n", + " base_unix = rhist.start_unix.min()\n", + " D_n = curr_unix - base_unix\n", + " S_n_durs = rhist[(rhist.start_unix > base_unix) & (rhist.start_unix <= curr_unix)] \\\n", + " [[f'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]]\n", + " S_n = S_n_durs.values.sum() // 2\n", + " return D_n, S_n\n", + "\n", + " rhists = []\n", + " for inter_no in sorted(rhistory.inter_no.unique()):\n", + " rhist = rhistory.copy()[rhistory.inter_no==inter_no]\n", + " rhist = rhist.drop_duplicates(subset=['start_unix']).reset_index(drop=True)\n", + "\n", + " # D_n 및 S_n 값 정의\n", + " rhist['D_n'] = 0 # D_n : 시간차이\n", + " rhist['S_n'] = 0 # S_n : 현시시간합\n", + " for n in range(len(rhist)):\n", + " curr_unix = rhist.iloc[n].start_unix # current start_unix\n", + " rhist.loc[n, ['D_n', 'S_n']] = calculate_DS(rhist, curr_unix)\n", + "\n", + " # 이전시각, 현재시각\n", + " prev_unix = rhist.loc[0, 'start_unix'] # previous start_unix\n", + " curr_unix = rhist.loc[1, 'start_unix'] # current start_unix\n", + "\n", + " # rhist의 마지막 행에 도달할 때까지 반복\n", + " while True:\n", + " n = rhist[rhist.start_unix==curr_unix].index[0]\n", + " cycle = rhist.loc[n, 'cycle']\n", + " D_n = rhist.loc[n, 'D_n']\n", + " S_n = rhist.loc[n, 'S_n']\n", + " # 참값인 경우\n", + " if (abs(D_n - S_n) <= 5):\n", + " pass\n", + " # 참값이 아닌 경우\n", + " else:\n", + " # 2-1-1. 결측치 처리 : 인접한 두 start_unix의 차이가 계획된 주기의 두 배보다 크면 결측이 일어났다고 판단, 신호계획의 현시시간으로 \"대체\"\n", + " if curr_unix - prev_unix >= 2 * cycle:\n", + " # prev_unix를 계획된 주기만큼 늘려가면서 한 행씩 채워나간다.\n", + " # (curr_unix와의 차이가 계획된 주기보다 작거나 같아질 때까지)\n", + " new_rows = []\n", + " while curr_unix - prev_unix > cycle:\n", + " prev_unix += cycle\n", + " # 신호 계획(prow) 불러오기\n", + " start_seconds = np.array(timetable.start_seconds)\n", + " idx = (start_seconds <= prev_unix).sum() - 1\n", + " start_hour = timetable.iloc[idx].start_hour\n", + " start_minute = timetable.iloc[idx].start_minute\n", + " prow = plan.copy()[(plan.inter_no==inter_no) & (plan.start_hour==start_hour) & (plan.start_minute==start_minute)] # planned row\n", + " # prow에서 필요한 부분을 rhist에 추가\n", + " prow['start_unix'] = prev_unix\n", + " prow = prow.drop(['start_hour', 'start_minute', 'offset'], axis=1)\n", + " cycle = prow.iloc[0].cycle\n", + " rhist = pd.concat([rhist, prow])\n", + " rhist = rhist.sort_values(by='start_unix').reset_index(drop=True)\n", + " n += 1\n", + "\n", + " # 2-1-2. 이상치 처리 : 비율에 따라 해당 행을 \"삭제\"(R_n <= 0.5) 또는 \"조정\"(R_n > 0.5)한다\n", + " R_n = (curr_unix - prev_unix) / cycle # R_n : 비율\n", + " # R_n이 0.5보다 작거나 같으면 해당 행을 삭제\n", + " if R_n <= 0.5:\n", + " rhist = rhist.drop(index=n).reset_index(drop=True)\n", + " # 행삭제에 따른 curr_unix, R_n 재정의\n", + " curr_unix = rhist.loc[n, 'start_unix']\n", + " R_n = (curr_unix - prev_unix) / cycle # R_n : 비율\n", + "\n", + " # R_n이 0.5보다 크면 해당 행 조정 (비율을 유지한 채로 현시시간 대체)\n", + " if R_n > 0.5:\n", + " # 신호 계획(prow) 불러오기\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 = plan[(plan.inter_no==inter_no) & (plan.start_hour==start_hour) & (plan.start_minute==start_minute)] # planned row\n", + " # 조정된 현시시간 (prow에 R_n을 곱하고 정수로 바꿈)\n", + " adjusted_dur = prow.copy()[[f'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]] * R_n\n", + " int_parts = adjusted_dur.iloc[0].apply(lambda x: int(x))\n", + " frac_parts = adjusted_dur.iloc[0] - int_parts\n", + " difference = round(adjusted_dur.iloc[0].sum()) - int_parts.sum()\n", + " for _ in range(difference): # 소수 부분이 가장 큰 상위 '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에 조정된 현시시간을 반영\n", + " rhist.loc[n, [f'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]] = int_parts.values\n", + " rhist.loc[n, 'cycle'] = int_parts.sum().sum() // 2\n", + "\n", + " if n == rhist.index[-1]:\n", + " break\n", + " prev_unix = curr_unix\n", + " curr_unix = rhist.loc[n+1, 'start_unix']\n", + "\n", + " # 생략해도 무방할 코드\n", + " rhist = rhist.reset_index(drop=True)\n", + " rhist = rhist.sort_values(by=['start_unix'])\n", + "\n", + " # D_n 및 S_n 값 재정의\n", + " for n in range(len(rhist)):\n", + " curr_unix = rhist.iloc[n].start_unix # current start_unix\n", + " rhist.loc[n, ['D_n', 'S_n']] = calculate_DS(rhist, curr_unix)\n", + " rhists.append(rhist)\n", + " rhists = pd.concat(rhists).sort_values(by=['start_unix','inter_no'])\n", + " rhists = rhists[rhists.start_unix >= present_time - 3600]\n", + " rhists = rhists.drop(columns=['D_n', 'S_n'])\n", + " return rhists" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "def make_hrhists(rhists, isplits, timetable):\n", + " # 계층화된 형태로 변환\n", + " hrhists = [] # hierarchied recent history\n", + " for i, row in rhists.iterrows():\n", + " inter_no = row.inter_no\n", + " start_unix = row.start_unix\n", + "\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", + " phas_As = [isplit[j][0] for j in isplit.keys()]\n", + " phas_Bs = [isplit[j][1] for j in isplit.keys()]\n", + " durs_A = row[[f'dura_A{j}' for j in range(1,9)]]\n", + " durs_B = row[[f'dura_B{j}' for j in range(1,9)]]\n", + " durations = []\n", + " for j in range(1, len(isplit)+1):\n", + " ja = isplit[j][0]\n", + " jb = isplit[j][1]\n", + " if ja == jb:\n", + " durations.append(min(durs_A[ja-1], durs_B[jb-1]))\n", + " else:\n", + " durations.append(abs(durs_A[ja-1] - durs_B[ja-1]))\n", + " new_rows = pd.DataFrame({'inter_no':[inter_no] * len(durations), 'start_unix':[start_unix] * len(durations),\n", + " 'phas_A':phas_As, 'phas_B':phas_Bs, 'duration':durations})\n", + " hrhists.append(new_rows)\n", + " hrhists = pd.concat(hrhists)\n", + " hrhists = hrhists.sort_values(by = ['start_unix', 'inter_no', 'phas_A', 'phas_B']).reset_index(drop=True)\n", + " return hrhists" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "def make_movements():\n", + " movements_path = '../../Data/tables/movements/'\n", + " movements_list = [pd.read_csv(movements_path + file, index_col=0) for file in tqdm(os.listdir(movements_path))]\n", + " movements = pd.concat(movements_list)\n", + " movements = movements.drop(columns=['start_unix'])\n", + " movements = movements.drop_duplicates()\n", + " movements = movements.sort_values(by=['inter_no', 'phas_A', 'phas_B'])\n", + " movements = movements.reset_index(drop=True)\n", + " movements.to_csv(movements_path + 'movements.csv')\n", + " return movements" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "def update_movement(hrhists, movement, movements):\n", + " # 중복을 제거하고 (inter_no, start_unix) 쌍을 만듭니다.\n", + " hrhists_inter_unix = set(hrhists[['inter_no', 'start_unix']].drop_duplicates().itertuples(index=False, name=None))\n", + " movement_inter_unix = set(movement[['inter_no', 'start_unix']].drop_duplicates().itertuples(index=False, name=None))\n", + "\n", + " # hrhists에는 있지만 movement에는 없는 (inter_no, start_unix) 쌍을 찾습니다.\n", + " missing_in_movement = hrhists_inter_unix - movement_inter_unix\n", + "\n", + " # 새로운 행들을 생성합니다.\n", + " new_rows = []\n", + " for inter_no, start_unix in missing_in_movement:\n", + " # movements에서 해당 inter_no의 데이터를 찾습니다.\n", + " new_row = movements[movements['inter_no'] == inter_no].copy()\n", + " # start_unix 값을 설정합니다.\n", + " new_row['start_unix'] = start_unix\n", + " new_rows.append(new_row)\n", + "\n", + " # 새로운 데이터프레임을 생성하고 기존 movement 데이터프레임과 합칩니다.\n", + " new_movement = pd.concat(new_rows, ignore_index=True)\n", + " movement_updated = pd.concat([movement, new_movement], ignore_index=True)\n", + " return movement_updated" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "def make_histid(present_time, movedur):\n", + " # 이동류 매칭 테이블에서 진입id, 진출id를 가져와서 붙임.\n", + " for i, row in movedur.iterrows():\n", + " inter_no = row.inter_no\n", + " start_unix = row.start_unix\n", + " # incoming and outgoing edges A\n", + " move_A = row.move_A\n", + " if move_A in [17, 18]:\n", + " inc_edge_A = np.nan\n", + " out_edge_A = np.nan\n", + " else:\n", + " match_A = matching[(matching.inter_no == inter_no) & (matching.move_no == move_A)].iloc[0]\n", + " inc_edge_A = match_A.inc_edge\n", + " out_edge_A = match_A.out_edge\n", + " movedur.loc[i, ['inc_edge_A', 'out_edge_A']] = [inc_edge_A, out_edge_A]\n", + " # incoming and outgoing edges B\n", + " move_B = row.move_B\n", + " if move_B in [17, 18]:\n", + " inc_edge_B = np.nan\n", + " out_edge_B = np.nan\n", + " else:\n", + " match_B = matching[(matching.inter_no == inter_no) & (matching.move_no == move_B)].iloc[0]\n", + " inc_edge_B = match_B.inc_edge\n", + " out_edge_B = match_B.out_edge\n", + " movedur.loc[i, ['inc_edge_B', 'out_edge_B']] = [inc_edge_B, out_edge_B]\n", + "\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", + " histid['node_id'] = histid['inter_no'].map(inter2node)\n", + " histid = histid[['inter_no', 'node_id', 'start_unix', 'phas_A', 'phas_B', 'duration', 'inc_edge_A', 'out_edge_A', 'inc_edge_B', 'out_edge_B']]\n", + " histid = histid[histid.start_unix > present_time - 3600]\n", + " return histid" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": {}, + "outputs": [], + "source": [ + "def histid_main(m):\n", + " '''\n", + " 통합테이블(histid)를 만드는 함수\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", + "\n", + " output : histid (통합테이블, HISTory with edge_IDs)\n", + " - 컬럼 : inter_no, node_id, start_unix, phas_A, phas_B, duration, inc_edge_A, out_edge_A, inc_edge_B, out_edge_B\n", + "\n", + " 주요 데이터, 중간산출물 및 결과물 :\n", + " # 데이터\n", + " - history : 신호이력 (inter_no, end_unix, dura_Aj, dura_Bj, cycle, offset)\n", + " - plan : 신호계획 (inter_no, start_hour, start_minute, dura_Aj, dura_Bj cycle, offset)\n", + " # 중간산출물\n", + " - rhists (recent history)\n", + " - history에서 현재 시각 이전의 데이터를 가져옴.\n", + " - end_unix를 start_unix로 변환\n", + " - 참값판단 프로세스(결측·이상치 처리)\n", + " - 컬럼 : inter_no, start_unix, dura_Aj, dura_Bj, cycle\n", + " - hrhists (hierarchized recent history)\n", + " - rhists를 계층화\n", + " - 컬럼 : inter_no, start_unix, phas_A, phas_B, duration\n", + " - movements\n", + " - 각 교차로에 대하여 현시별로 이동류를 정해놓음.\n", + " - join시 사용하기 위함.\n", + " - 한 번 만들어놓고 두고두고 사용함.\n", + " - 컬럼 : inter_no, phas_A, phas_B, move_A, move_B\n", + " - movement\n", + " - 현재 시점에서의 이동류정보\n", + " - 컬럼 : inter_no, phas_A, phas_B, move_A, move_B, start_unix\n", + " - movement_updated\n", + " - movement와 hrhists를 join하기 전에, movement에는 없지만 hrhists에는 있는 start_unix에 대한 이동류 정보를 가져와 movement에 붙임\n", + " - 이동류정보는 앞서 정의한 movements에서 가져옴.\n", + " - 컬럼 : inter_no, phas_A, phas_B, move_A, move_B, start_unix\n", + " - movedur\n", + " - hrhists와 movement_updated를 join\n", + " - 컬럼 : inter_no, phas_A, phas_B, move_A, move_B, start_unix, duration\n", + " # 결과\n", + "\n", + " '''\n", + " midnight = int(datetime(2024, 1, 5, 0, 0, 0).timestamp())\n", + " next_day = int(datetime(2024, 1, 6, 0, 0, 0).timestamp())\n", + " fmins = range(midnight, next_day, 300) # fmins : unix time by Five MINuteS\n", + "\n", + " # 사용할 표준 테이블 목록\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", + "\n", + " # 참고할 딕셔너리, 데이터프레임 등 목록\n", + " splits, isplits = make_splits(plan)\n", + " timetable = make_timetable(plan)\n", + "\n", + " # 현재시점\n", + " present_time = fmins[m]\n", + " print(datetime.fromtimestamp(present_time))\n", + "\n", + " # rhists, hrhists\n", + " rhists = make_rhists(present_time, timetable, plan, history)\n", + " hrhists = make_hrhists(rhists, isplits, timetable)\n", + "\n", + " # movements, movement, movement_updated\n", + " movements = pd.read_csv('../../data/tables/movements/movements.csv', index_col=0)\n", + " movement = pd.read_csv(f'../../Data/tables/movements/movements_{present_time}.csv', index_col=0)\n", + " movement_updated = update_movement(hrhists, movement, movements)\n", + "\n", + " # movedur\n", + " movedur = pd.merge(movement_updated, hrhists, how='inner', on=['inter_no', 'start_unix', 'phas_A', 'phas_B']) # 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", + "\n", + " # histid\n", + " histid = make_histid(present_time, movedur)\n", + "\n", + " \n", + " # hrhists['start_dt'] = hrhists['start_unix'].map(lambda x:datetime.fromtimestamp(x))\n", + "\n", + " return histid" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2024-01-05 02:30:00\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \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_nonode_idstart_unixphas_Aphas_Bdurationinc_edge_Aout_edge_Ainc_edge_Bout_edge_B
0175u0017043858401137-571542797_02571500487_01-571500487_01571542797_02
1175u0017043858402239-571500487_01571545870_01-571542797_02571510153_01
2175u0017043858403325571545870_02571510153_01571545870_02571542797_02
3175u0017043858403430571545870_02571510153_01571510153_02571545870_01
4175u0017043858404429571510153_02571500487_01571510153_02571545870_01
.................................
764201i817043892203317571500617_02571500618_01571500618_02571500617_01
765201i817043892204458571500617_02571500618_01571500617_02571500569_01
766201i817043892205517571500583_01571500617_01571500583_01571500569_01
767202i917043892201139571510152_02-571510152_01571510152_01571510152_01.65
768202i9170438922022101NaNNaNNaNNaN
\n", + "

769 rows × 10 columns

\n", + "
" + ], + "text/plain": [ + " inter_no node_id start_unix phas_A phas_B duration inc_edge_A \\\n", + "0 175 u00 1704385840 1 1 37 -571542797_02 \n", + "1 175 u00 1704385840 2 2 39 -571500487_01 \n", + "2 175 u00 1704385840 3 3 25 571545870_02 \n", + "3 175 u00 1704385840 3 4 30 571545870_02 \n", + "4 175 u00 1704385840 4 4 29 571510153_02 \n", + ".. ... ... ... ... ... ... ... \n", + "764 201 i8 1704389220 3 3 17 571500617_02 \n", + "765 201 i8 1704389220 4 4 58 571500617_02 \n", + "766 201 i8 1704389220 5 5 17 571500583_01 \n", + "767 202 i9 1704389220 1 1 39 571510152_02 \n", + "768 202 i9 1704389220 2 2 101 NaN \n", + "\n", + " out_edge_A inc_edge_B out_edge_B \n", + "0 571500487_01 -571500487_01 571542797_02 \n", + "1 571545870_01 -571542797_02 571510153_01 \n", + "2 571510153_01 571545870_02 571542797_02 \n", + "3 571510153_01 571510153_02 571545870_01 \n", + "4 571500487_01 571510153_02 571545870_01 \n", + ".. ... ... ... \n", + "764 571500618_01 571500618_02 571500617_01 \n", + "765 571500618_01 571500617_02 571500569_01 \n", + "766 571500617_01 571500583_01 571500569_01 \n", + "767 -571510152_01 571510152_01 571510152_01.65 \n", + "768 NaN NaN NaN \n", + "\n", + "[769 rows x 10 columns]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2024-01-05 02:35:00\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \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_nonode_idstart_unixphas_Aphas_Bdurationinc_edge_Aout_edge_Ainc_edge_Bout_edge_B
0201i817043861391124-571500569_01571500583_02-571500569_01571500618_01
1201i817043861392224571500618_02571500583_02571500618_02571500617_01
2201i817043861393317571500617_02571500618_01571500618_02571500617_01
3201i817043861394458571500617_02571500618_01571500617_02571500569_01
4201i817043861395517571500583_01571500617_01571500583_01571500569_01
.................................
768175u0017043895204429571510153_02571500487_01571510153_02571545870_01
769206i717043895201133-571511538_02571542073_02571542073_01571511538_02
770206i717043895202235NaNNaNNaNNaN
771206i717043895203326-571511538_02571542073_02571542073_01571511538_02
772206i717043895204426NaNNaNNaNNaN
\n", + "

773 rows × 10 columns

\n", + "
" + ], + "text/plain": [ + " inter_no node_id start_unix phas_A phas_B duration inc_edge_A \\\n", + "0 201 i8 1704386139 1 1 24 -571500569_01 \n", + "1 201 i8 1704386139 2 2 24 571500618_02 \n", + "2 201 i8 1704386139 3 3 17 571500617_02 \n", + "3 201 i8 1704386139 4 4 58 571500617_02 \n", + "4 201 i8 1704386139 5 5 17 571500583_01 \n", + ".. ... ... ... ... ... ... ... \n", + "768 175 u00 1704389520 4 4 29 571510153_02 \n", + "769 206 i7 1704389520 1 1 33 -571511538_02 \n", + "770 206 i7 1704389520 2 2 35 NaN \n", + "771 206 i7 1704389520 3 3 26 -571511538_02 \n", + "772 206 i7 1704389520 4 4 26 NaN \n", + "\n", + " out_edge_A inc_edge_B out_edge_B \n", + "0 571500583_02 -571500569_01 571500618_01 \n", + "1 571500583_02 571500618_02 571500617_01 \n", + "2 571500618_01 571500618_02 571500617_01 \n", + "3 571500618_01 571500617_02 571500569_01 \n", + "4 571500617_01 571500583_01 571500569_01 \n", + ".. ... ... ... \n", + "768 571500487_01 571510153_02 571545870_01 \n", + "769 571542073_02 571542073_01 571511538_02 \n", + "770 NaN NaN NaN \n", + "771 571542073_02 571542073_01 571511538_02 \n", + "772 NaN NaN NaN \n", + "\n", + "[773 rows x 10 columns]" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "for m in range(30, 32):\n", + " histid = histid_main(m)\n", + " display(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 +} diff --git a/Analysis/0109_preprocess/0122_preprocess_9.ipynb b/Analysis/0109_preprocess/0122_preprocess_9.ipynb index f965c317a..b2236f2f2 100644 --- a/Analysis/0109_preprocess/0122_preprocess_9.ipynb +++ b/Analysis/0109_preprocess/0122_preprocess_9.ipynb @@ -26,7982 +26,755 @@ "cell_type": "code", "execution_count": 2, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - " 0%| | 0/17280 [00:00\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \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": 6, - "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
01751A8179004-571542797_02571500487_01i0
11751B4003176-571500487_01571542797_02i0
21752A7001095-571500487_01571545870_01i0
31752B3179270-571542797_02571510153_01i0
41753A6090270571545870_02571510153_01i0
51753B1090180571545870_02571542797_02i0
61754A5268000571510153_02571500487_01i0
71754B2270090571510153_02571545870_01i0
81761A8180000-571542810_01-571542797_02.99i1
91761B4359180571542797_02.99571542810_01i1
101762A8180000-571542810_01-571542797_02.99i1
111762B3180270-571542810_01571543469_01i1
121763A5270356571543469_02-571542797_02.99i1
131763B18NaNNaNNaNNaNNaNNaNi1
141771A8180000-571542809_01571542811_01i2
151771B4001176571542811_02571542809_01i2
161772A7000090571542811_02571542107_01i2
171772B3179270-571542809_01571542809_01i2
181773A17NaNNaNNaNNaNNaNNaNi2
191773B18NaNNaNNaNNaNNaNNaNi2
201774A5268000-571542809_01571542811_01i2
211774B1090180571542107_02571542809_01i2
221781A8180000571540304_02571556450_01i3
231781B4000180571556450_02571540304_01i3
241782A7000090571556450_02571500475_01i3
251782B3180270571540304_02571540303_01i3
261783A5270000571540303_02.21571556450_01i3
271783B2270090571540303_02.21571500475_01i3
281784A6090270-571500475_01571540303_01i3
291784B1090180-571500475_01571540304_01i3
302011A8180000-571500569_01571500583_02i8
312011B3180270-571500569_01571500618_01i8
322012A5270000571500618_02571500583_02i8
332012B2270090571500618_02571500617_01i8
342013A6090270571500617_02571500618_01i8
352013B2270090571500618_02571500617_01i8
362014A6090270571500617_02571500618_01i8
372014B1090180571500617_02571500569_01i8
382015A7000090571500583_01571500617_01i8
392015B4000180571500583_01571500569_01i8
402021A6090270571510152_02-571510152_01i9
412021B2270090571510152_01571510152_01.65i9
422022A17NaNNaNNaNNaNNaNNaNi9
432022B18NaNNaNNaNNaNNaNNaNi9
442061A8180000-571511538_02571542073_02i7
452061B4000180571542073_01571511538_02i7
462062A17NaNNaNNaNNaNNaNNaNi7
472062B18NaNNaNNaNNaNNaNNaNi7
482063A8180000-571511538_02571542073_02i7
492063B4000180571542073_01571511538_02i7
502064A17NaNNaNNaNNaNNaNNaNi7
512064B18NaNNaNNaNNaNNaNNaNi7
522101A6090270-571542115_01571500535_01i6
532101B18NaNNaNNaNNaNNaNNaNi6
542102A5268000571500535_02.18571511538_01i6
552102B2270090571500535_02.18571542115_01i6
562103A7359090571511538_02.121571542115_01i6
572103B4000180571511538_02.121571500585_01i6
582104A8180000571500585_02571511538_01i6
592104B3180270571500585_02571500535_01i6
\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 \n", - "\n", - " inc_edge out_edge node_id \n", - "0 -571542797_02 571500487_01 i0 \n", - "1 -571500487_01 571542797_02 i0 \n", - "2 -571500487_01 571545870_01 i0 \n", - "3 -571542797_02 571510153_01 i0 \n", - "4 571545870_02 571510153_01 i0 \n", - "5 571545870_02 571542797_02 i0 \n", - "6 571510153_02 571500487_01 i0 \n", - "7 571510153_02 571545870_01 i0 \n", - "8 -571542810_01 -571542797_02.99 i1 \n", - "9 571542797_02.99 571542810_01 i1 \n", - "10 -571542810_01 -571542797_02.99 i1 \n", - "11 -571542810_01 571543469_01 i1 \n", - "12 571543469_02 -571542797_02.99 i1 \n", - "13 NaN NaN i1 \n", - "14 -571542809_01 571542811_01 i2 \n", - "15 571542811_02 571542809_01 i2 \n", - "16 571542811_02 571542107_01 i2 \n", - "17 -571542809_01 571542809_01 i2 \n", - "18 NaN NaN i2 \n", - "19 NaN NaN i2 \n", - "20 -571542809_01 571542811_01 i2 \n", - "21 571542107_02 571542809_01 i2 \n", - "22 571540304_02 571556450_01 i3 \n", - "23 571556450_02 571540304_01 i3 \n", - "24 571556450_02 571500475_01 i3 \n", - "25 571540304_02 571540303_01 i3 \n", - "26 571540303_02.21 571556450_01 i3 \n", - "27 571540303_02.21 571500475_01 i3 \n", - "28 -571500475_01 571540303_01 i3 \n", - "29 -571500475_01 571540304_01 i3 \n", - "30 -571500569_01 571500583_02 i8 \n", - "31 -571500569_01 571500618_01 i8 \n", - "32 571500618_02 571500583_02 i8 \n", - "33 571500618_02 571500617_01 i8 \n", - "34 571500617_02 571500618_01 i8 \n", - "35 571500618_02 571500617_01 i8 \n", - "36 571500617_02 571500618_01 i8 \n", - "37 571500617_02 571500569_01 i8 \n", - "38 571500583_01 571500617_01 i8 \n", - "39 571500583_01 571500569_01 i8 \n", - "40 571510152_02 -571510152_01 i9 \n", - "41 571510152_01 571510152_01.65 i9 \n", - "42 NaN NaN i9 \n", - "43 NaN NaN i9 \n", - "44 -571511538_02 571542073_02 i7 \n", - "45 571542073_01 571511538_02 i7 \n", - "46 NaN NaN i7 \n", - "47 NaN NaN i7 \n", - "48 -571511538_02 571542073_02 i7 \n", - "49 571542073_01 571511538_02 i7 \n", - "50 NaN NaN i7 \n", - "51 NaN NaN i7 \n", - "52 -571542115_01 571500535_01 i6 \n", - "53 NaN NaN i6 \n", - "54 571500535_02.18 571511538_01 i6 \n", - "55 571500535_02.18 571542115_01 i6 \n", - "56 571511538_02.121 571542115_01 i6 \n", - "57 571511538_02.121 571500585_01 i6 \n", - "58 571500585_02 571511538_01 i6 \n", - "59 571500585_02 571500535_01 i6 " - ] - }, - "execution_count": 6, - "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.sort_values(by=['inter_no','phase_no','ring_type']).reset_index(drop=True)\n", - "match5" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array(['u00', 'u20', 'u30', 'u31', 'u32', 'u60'], dtype=object)" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# 유턴/연동교차로에 대하여 진입ID, 진출ID 부여\n", - "node2inter = dict(zip(inter_node['node_id'], inter_node['inter_no']))\n", - "\n", - "uturn = pd.read_csv('../../Data/tables/child_uturn.csv')\n", - "coord = pd.read_csv('../../Data/tables/child_coord.csv')\n", - "\n", - "child_ids = inter_node[inter_node.inter_type=='child'].node_id.unique()\n", - "ch2pa = {} # child to parent\n", - "for child_id in child_ids:\n", - " parent_no = inter_node[inter_node.node_id==child_id].inter_no.iloc[0]\n", - " sub_inter_node = inter_node[inter_node.inter_no==parent_no]\n", - " ch2pa[child_id] = sub_inter_node[sub_inter_node.inter_type=='parent'].iloc[0].node_id\n", - "directions = ['북', '북동', '동', '남동', '남', '남서', '서', '북서'] # 정북기준 시계방향으로 8방향\n", - "u_ids = uturn.child_id.unique()\n", - "u_ids" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "u00 i0 좌회전시 북\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", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \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
01751A8179004NaNNaNu00
11751B4003176NaNNaNu00
21752A19001095571500487_02571500487_01.32u00
31752B3179270NaNNaNu00
41753A6090270NaNNaNu00
51753B1090180NaNNaNu00
61754A5268000NaNNaNu00
71754B2270090NaNNaNu00
\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 19 북 동 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", - "\n", - " inc_edge out_edge node_id \n", - "0 NaN NaN u00 \n", - "1 NaN NaN u00 \n", - "2 571500487_02 571500487_01.32 u00 \n", - "3 NaN NaN u00 \n", - "4 NaN NaN u00 \n", - "5 NaN NaN u00 \n", - "6 NaN NaN u00 \n", - "7 NaN NaN u00 " - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "u20 i2 보행신호시 북\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", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \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
01771A8180000NaNNaNu20
11771B4001176NaNNaNu20
21772A7000090NaNNaNu20
31772B3179270NaNNaNu20
41773A17NaNNaNNaNNaN571542810_01.51571542810_02u20
51773B18NaNNaNNaNNaNNaNNaNu20
61774A5268000NaNNaNu20
71774B1090180NaNNaNu20
\n", - "
" - ], - "text/plain": [ - " inter_no phase_no ring_type move_no inc_dir out_dir inc_angle out_angle \\\n", - "0 177 1 A 8 남 북 180 000 \n", - "1 177 1 B 4 북 남 001 176 \n", - "2 177 2 A 7 북 동 000 090 \n", - "3 177 2 B 3 남 서 179 270 \n", - "4 177 3 A 17 NaN NaN NaN NaN \n", - "5 177 3 B 18 NaN NaN NaN NaN \n", - "6 177 4 A 5 서 북 268 000 \n", - "7 177 4 B 1 동 남 090 180 \n", - "\n", - " inc_edge out_edge node_id \n", - "0 NaN NaN u20 \n", - "1 NaN NaN u20 \n", - "2 NaN NaN u20 \n", - "3 NaN NaN u20 \n", - "4 571542810_01.51 571542810_02 u20 \n", - "5 NaN NaN u20 \n", - "6 NaN NaN u20 \n", - "7 NaN NaN u20 " - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "u30 i3 보행신호시 북\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", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \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
01781A8180000NaNNaNu30
11781B4000180NaNNaNu30
21782A7000090NaNNaNu30
31782B3180270NaNNaNu30
41783A5270000NaNNaNu30
51783B2270090NaNNaNu30
61784A19090270571556452_01571556452_02u30
71784B1090180NaNNaNu30
\n", - "
" - ], - "text/plain": [ - " inter_no phase_no ring_type move_no inc_dir out_dir inc_angle out_angle \\\n", - "0 178 1 A 8 남 북 180 000 \n", - "1 178 1 B 4 북 남 000 180 \n", - "2 178 2 A 7 북 동 000 090 \n", - "3 178 2 B 3 남 서 180 270 \n", - "4 178 3 A 5 서 북 270 000 \n", - "5 178 3 B 2 서 동 270 090 \n", - "6 178 4 A 19 동 서 090 270 \n", - "7 178 4 B 1 동 남 090 180 \n", - "\n", - " inc_edge out_edge node_id \n", - "0 NaN NaN u30 \n", - "1 NaN NaN u30 \n", - "2 NaN NaN u30 \n", - "3 NaN NaN u30 \n", - "4 NaN NaN u30 \n", - "5 NaN NaN u30 \n", - "6 571556452_01 571556452_02 u30 \n", - "7 NaN NaN u30 " - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "u31 i3 보행신호시 동\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", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \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
01781A19180000571500475_02571500475_01.26u31
11781B4000180NaNNaNu31
21782A7000090NaNNaNu31
31782B3180270NaNNaNu31
41783A5270000NaNNaNu31
51783B2270090NaNNaNu31
61784A6090270NaNNaNu31
71784B1090180NaNNaNu31
\n", - "
" - ], - "text/plain": [ - " inter_no phase_no ring_type move_no inc_dir out_dir inc_angle out_angle \\\n", - "0 178 1 A 19 남 북 180 000 \n", - "1 178 1 B 4 북 남 000 180 \n", - "2 178 2 A 7 북 동 000 090 \n", - "3 178 2 B 3 남 서 180 270 \n", - "4 178 3 A 5 서 북 270 000 \n", - "5 178 3 B 2 서 동 270 090 \n", - "6 178 4 A 6 동 서 090 270 \n", - "7 178 4 B 1 동 남 090 180 \n", - "\n", - " inc_edge out_edge node_id \n", - "0 571500475_02 571500475_01.26 u31 \n", - "1 NaN NaN u31 \n", - "2 NaN NaN u31 \n", - "3 NaN NaN u31 \n", - "4 NaN NaN u31 \n", - "5 NaN NaN u31 \n", - "6 NaN NaN u31 \n", - "7 NaN NaN u31 " - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "u32 i3 보행신호시 서\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", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \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
01781A8180000NaNNaNu32
11781B19000180571540303_02-571540303_02u32
21782A7000090NaNNaNu32
31782B3180270NaNNaNu32
41783A5270000NaNNaNu32
51783B2270090NaNNaNu32
61784A6090270NaNNaNu32
71784B1090180NaNNaNu32
\n", - "
" - ], - "text/plain": [ - " inter_no phase_no ring_type move_no inc_dir out_dir inc_angle out_angle \\\n", - "0 178 1 A 8 남 북 180 000 \n", - "1 178 1 B 19 북 남 000 180 \n", - "2 178 2 A 7 북 동 000 090 \n", - "3 178 2 B 3 남 서 180 270 \n", - "4 178 3 A 5 서 북 270 000 \n", - "5 178 3 B 2 서 동 270 090 \n", - "6 178 4 A 6 동 서 090 270 \n", - "7 178 4 B 1 동 남 090 180 \n", - "\n", - " inc_edge out_edge node_id \n", - "0 NaN NaN u32 \n", - "1 571540303_02 -571540303_02 u32 \n", - "2 NaN NaN u32 \n", - "3 NaN NaN u32 \n", - "4 NaN NaN u32 \n", - "5 NaN NaN u32 \n", - "6 NaN NaN u32 \n", - "7 NaN NaN u32 " - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "u60 i6 직좌시 서\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", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \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
02101A6090270NaNNaNu60
12101B18NaNNaNNaNNaNNaNNaNu60
22102A19268000571500535_02-571500535_02u60
32102B19270090571500535_02-571500535_02u60
42103A7359090NaNNaNu60
52103B4000180NaNNaNu60
62104A8180000NaNNaNu60
72104B3180270NaNNaNu60
\n", - "
" - ], - "text/plain": [ - " inter_no phase_no ring_type move_no inc_dir out_dir inc_angle out_angle \\\n", - "0 210 1 A 6 동 서 090 270 \n", - "1 210 1 B 18 NaN NaN NaN NaN \n", - "2 210 2 A 19 서 북 268 000 \n", - "3 210 2 B 19 서 동 270 090 \n", - "4 210 3 A 7 북 동 359 090 \n", - "5 210 3 B 4 북 남 000 180 \n", - "6 210 4 A 8 남 북 180 000 \n", - "7 210 4 B 3 남 서 180 270 \n", - "\n", - " inc_edge out_edge node_id \n", - "0 NaN NaN u60 \n", - "1 NaN NaN u60 \n", - "2 571500535_02 -571500535_02 u60 \n", - "3 571500535_02 -571500535_02 u60 \n", - "4 NaN NaN u60 \n", - "5 NaN NaN u60 \n", - "6 NaN NaN u60 \n", - "7 NaN NaN u60 " - ] - }, - "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", - "
inter_nophase_noring_typemove_noinc_dirout_dirinc_angleout_angleinc_edgeout_edgenode_id
01781A20NaNNaNNaNNaNNaNNaNc30
11781B20NaNNaNNaNNaNNaNNaNc30
21782A20NaNNaNNaNNaN571542116_01-571542116_02.96c30
31782B20NaNNaNNaNNaN571542116_02.96571542116_02.164c30
41783A20NaNNaNNaNNaN571542116_01-571542116_02.96c30
51783B20NaNNaNNaNNaN571542116_02.96571542116_02.164c30
61784A20NaNNaNNaNNaN571542116_01-571542116_02.96c30
71784B20NaNNaNNaNNaN571542116_02.96571542116_02.164c30
\n", - "
" - ], - "text/plain": [ - " inter_no phase_no ring_type move_no inc_dir out_dir inc_angle \\\n", - "0 178 1 A 20 NaN NaN NaN \n", - "1 178 1 B 20 NaN NaN NaN \n", - "2 178 2 A 20 NaN NaN NaN \n", - "3 178 2 B 20 NaN NaN NaN \n", - "4 178 3 A 20 NaN NaN NaN \n", - "5 178 3 B 20 NaN NaN NaN \n", - "6 178 4 A 20 NaN NaN NaN \n", - "7 178 4 B 20 NaN NaN NaN \n", - "\n", - " out_angle inc_edge out_edge node_id \n", - "0 NaN NaN NaN c30 \n", - "1 NaN NaN NaN c30 \n", - "2 NaN 571542116_01 -571542116_02.96 c30 \n", - "3 NaN 571542116_02.96 571542116_02.164 c30 \n", - "4 NaN 571542116_01 -571542116_02.96 c30 \n", - "5 NaN 571542116_02.96 571542116_02.164 c30 \n", - "6 NaN 571542116_01 -571542116_02.96 c30 \n", - "7 NaN 571542116_02.96 571542116_02.164 c30 " - ] - }, - "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", - "
inter_nophase_noring_typemove_noinc_dirout_dirinc_angleout_angleinc_edgeout_edgenode_id
01751A8179004-571542797_02571500487_01i0
11751B4003176-571500487_01571542797_02i0
21752A7001095-571500487_01571545870_01i0
31752B3179270-571542797_02571510153_01i0
41753A6090270571545870_02571510153_01i0
....................................
32102B19270090571500535_02-571500535_02u60
42103A7359090NaNNaNu60
52103B4000180NaNNaNu60
62104A8180000NaNNaNu60
72104B3180270NaNNaNu60
\n", - "

116 rows × 11 columns

\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", - ".. ... ... ... ... ... ... ... ... \n", - "3 210 2 B 19 서 동 270 090 \n", - "4 210 3 A 7 북 동 359 090 \n", - "5 210 3 B 4 북 남 000 180 \n", - "6 210 4 A 8 남 북 180 000 \n", - "7 210 4 B 3 남 서 180 270 \n", - "\n", - " inc_edge out_edge node_id \n", - "0 -571542797_02 571500487_01 i0 \n", - "1 -571500487_01 571542797_02 i0 \n", - "2 -571500487_01 571545870_01 i0 \n", - "3 -571542797_02 571510153_01 i0 \n", - "4 571545870_02 571510153_01 i0 \n", - ".. ... ... ... \n", - "3 571500535_02 -571500535_02 u60 \n", - "4 NaN NaN u60 \n", - "5 NaN NaN u60 \n", - "6 NaN NaN u60 \n", - "7 NaN NaN u60 \n", - "\n", - "[116 rows x 11 columns]" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# 유턴/연동교차로에 대하여 진입ID, 진출ID 부여\n", - "node2inter = dict(zip(inter_node['node_id'], inter_node['inter_no']))\n", - "\n", - "uturn = pd.read_csv('../../Data/tables/child_uturn.csv')\n", - "coord = pd.read_csv('../../Data/tables/child_coord.csv')\n", - "child_ids = inter_node[inter_node.inter_type=='child'].node_id.unique()\n", - "ch2pa = {} # child to parent\n", - "for child_id in child_ids:\n", - " parent_no = inter_node[inter_node.node_id==child_id].inter_no.iloc[0]\n", - " sub_inter_node = inter_node[inter_node.inter_no==parent_no]\n", - " ch2pa[child_id] = sub_inter_node[sub_inter_node.inter_type=='parent'].iloc[0].node_id\n", - "directions = ['북', '북동', '동', '남동', '남', '남서', '서', '북서'] # 정북기준 시계방향으로 8방향\n", - "u_ids = uturn.child_id.unique()\n", - "# 각 child uturn node에 대하여 (inc_edge_id, out_edge_id) 부여\n", - "cmatches = []\n", - "for _, row in uturn.iterrows():\n", - " child_id = row.child_id\n", - " parent_id = row.parent_id\n", - " direction = row.direction\n", - " condition = row.condition\n", - " inc_edge_id = row.inc_edge\n", - " out_edge_id = row.out_edge\n", - " ind = directions.index(direction)\n", - " if condition == \"좌회전시\":\n", - " print(child_id, parent_id, condition, direction)\n", - " inc_dire = direction\n", - " out_dire_A = out_dire_B = directions[(ind + 2) % len(directions)]\n", - " elif condition == \"직진시\":\n", - " print(child_id, parent_id, condition, direction)\n", - " inc_dire = direction\n", - " out_dire_A = out_dire_B = directions[(ind + 4) % len(directions)]\n", - " elif condition == \"직좌시\":\n", - " print(child_id, parent_id, condition, direction)\n", - " inc_dire = direction\n", - " out_dire_A = directions[(ind + 2) % len(directions)]\n", - " out_dire_B = directions[(ind + 4) % len(directions)]\n", - " elif condition == \"보행신호시\":\n", - " print(child_id, parent_id, condition, direction)\n", - " inc_dire = directions[(ind + 2) % len(directions)]\n", - " out_dire_A = directions[(ind - 2) % len(directions)]\n", - " out_dire_B = directions[(ind - 2) % len(directions)]\n", - " cmatch = match5.copy()[match5.node_id==parent_id] # match dataframe for a child node\n", - " cmatch = cmatch.sort_values(by=['phase_no', 'ring_type']).reset_index(drop=True)\n", - " cmatch['node_id'] = child_id\n", - " cmatch[['inc_edge', 'out_edge']] = np.nan\n", - " if condition == '직좌시':\n", - " ap = cmatch[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_A)].phase_no.iloc[0]\n", - " bp = cmatch[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_B)].phase_no.iloc[0]\n", - " # 직진과 좌회전이 같은 현시에 있는 경우에만 (inc_edge_id, out_edge_id)를 부여한다.\n", - " if ap == bp:\n", - " cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_A), ['inc_edge', 'out_edge']] = [inc_edge_id, out_edge_id]\n", - " cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_B), ['inc_edge', 'out_edge']] = [inc_edge_id, out_edge_id]\n", - " elif condition == '보행신호시':\n", - " cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_A), ['inc_edge', 'out_edge']] = [inc_edge_id, out_edge_id]\n", - " cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_B), ['inc_edge', 'out_edge']] = [inc_edge_id, out_edge_id]\n", - " # 이동류번호가 17(보행신호)이면서 유턴노드방향으로 가는 신호가 없으면 (inc_edge_id, out_edge_id)를 부여한다.\n", - " cmatch.loc[(cmatch.move_no==17) & (cmatch.out_dir!=direction), ['inc_edge', 'out_edge']] = [inc_edge_id, out_edge_id]\n", - " else:\n", - " cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_A), ['inc_edge', 'out_edge']] = [inc_edge_id, out_edge_id]\n", - " cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_B), ['inc_edge', 'out_edge']] = [inc_edge_id, out_edge_id]\n", - " # 유턴신호의 이동류번호를 19로 부여한다.\n", - " cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_A), 'move_no'] = 19\n", - " cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_B), 'move_no'] = 19\n", - " display(cmatch)\n", - " cmatches.append(cmatch)\n", - "\n", - "# 각 child coordination node에 대하여 (inc_edge_id, out_edge_id) 부여\n", - "coord['inter_no'] = coord['parent_id'].map(node2inter)\n", - "coord = coord.rename(columns={'child_id':'node_id'})\n", - "coord[['inc_dir', 'out_dir', 'inc_angle','out_angle']] = np.nan\n", - "coord['move_no'] = 20\n", - "coord = coord[['inter_no', 'phase_no', 'ring_type', 'move_no', 'inc_dir', 'out_dir', 'inc_angle','out_angle', 'inc_edge', 'out_edge', 'node_id']]\n", - "# display(coord)\n", - "cmatches = pd.concat(cmatches)\n", - "display(coord)\n", - "match6 = pd.concat([match5, cmatches, coord]).drop_duplicates().sort_values(by=['inter_no', 'node_id', 'phase_no', 'ring_type'])\n", - "# with pd.option_context('display.max_rows', None, 'display.max_columns', None):\n", - "match6.to_csv('../../Data/tables/matching/match6.csv')\n", - "display(match6)" - ] - }, - { - "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", - " \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
........................
692108571500585_02571511538_01i6
7021021571511538_02.121571500535_01i6
7121021571500535_02.18571500585_01i6
7221021571500585_02571542115_01i6
7321021-571542115_01571511538_01i6
\n", - "

74 rows × 7 columns

\n", - "
" - ], - "text/plain": [ - " inter_no move_no inc_dir out_dir inc_edge out_edge node_id\n", - "0 175 1 동 남 571545870_02 571542797_02 i0\n", - "1 175 2 서 동 571510153_02 571545870_01 i0\n", - "2 175 3 남 서 -571542797_02 571510153_01 i0\n", - "3 175 4 북 남 -571500487_01 571542797_02 i0\n", - "4 175 5 서 북 571510153_02 571500487_01 i0\n", - ".. ... ... ... ... ... ... ...\n", - "69 210 8 남 북 571500585_02 571511538_01 i6\n", - "70 210 21 북 서 571511538_02.121 571500535_01 i6\n", - "71 210 21 서 남 571500535_02.18 571500585_01 i6\n", - "72 210 21 남 동 571500585_02 571542115_01 i6\n", - "73 210 21 동 북 -571542115_01 571511538_01 i6\n", - "\n", - "[74 rows x 7 columns]" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# 이동류 매칭\n", - "# 각 교차로에 대하여, 가능한 모든 이동류(1~18, 21)에 대한 진입·진출엣지ID를 지정한다.\n", - "# 모든 이동류에 대해 지정하므로, 시차제시 이전과 다른 이동류가 등장하더라도 항상 진입·진출 엣지 ID를 지정할 수 있다.\n", - "match7 = match6.copy()\n", - "match7 = match7[['inter_no', 'move_no', 'inc_dir', 'out_dir', 'inc_edge', 'out_edge', 'node_id']]\n", - "\n", - "parent_ids = sorted(inter_node[inter_node.inter_type=='parent'].node_id.unique())\n", - "child_ids = sorted(inter_node[inter_node.inter_type=='child'].node_id.unique())\n", - "\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 node_id in parent_ids:\n", - " dires = match7[match7.node_id == node_id][['inc_dir','out_dir']].values.flatten()\n", - " dires = {dire for dire in dires if type(dire)==str}\n", - " pdires[node_id] = dires\n", - "# (3) 각 (교차로, 진입방향) 별 진입id 목록 : inc2id (incoming direction to incoming edge_id)\n", - "inc2id = {}\n", - "for node_id in parent_ids:\n", - " for inc_dir in pdires[node_id]:\n", - " df = match7[(match7.node_id==node_id) & (match7.inc_dir==inc_dir)]\n", - " inc2id[(node_id, inc_dir)] = df.inc_edge.iloc[0]\n", - "# (4) 각 (교차로, 진출방향) 별 진출id 목록 : out2id (outgoing direction to outgoing edge_id)\n", - "out2id = {}\n", - "for node_id in parent_ids:\n", - " for out_dir in pdires[node_id]:\n", - " df = match7[(match7.node_id==node_id) & (match7.out_dir==out_dir)]\n", - " out2id[(node_id, out_dir)] = df.out_edge.iloc[0]\n", - "# (5) 각 교차로별 가능한 (진입방향, 진출방향) 목록 : pflow (possible flows)\n", - "pflow = {}\n", - "for node_id in parent_ids:\n", - " pflow[node_id] = [flow for flow in flows if set(flow).issubset(pdires[node_id])]\n", - "# (6) 가능한 이동류에 대하여 진입id, 진출id 배정 : matching\n", - "node2inter = dict(zip(match7['node_id'], match7['inter_no']))\n", - "dires_right = ['북', '서', '남', '동', '북'] # ex (북, 서), (서, 남) 등은 우회전 flow\n", - "matching = []\n", - "for node_id in parent_ids:\n", - " inter_no = node2inter[node_id]\n", - " # 좌회전과 직진(1 ~ 16)\n", - " for (inc_dir, out_dir) in pflow[node_id]:\n", - " move_no = nema[(nema.inc_dir==inc_dir) & (nema.out_dir==out_dir)].move_no.iloc[0]\n", - " inc_edge = inc2id[(node_id, inc_dir)]\n", - " out_edge = out2id[(node_id, 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[node_id]):\n", - " inc_edge = inc2id[(node_id, inc_dir)]\n", - " out_edge = out2id[(node_id, 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.append(match7[match7.node_id.isin(child_ids)])\n", - "matching = pd.concat(matching)\n", - "matching = matching.dropna().sort_values(by=['inter_no', 'node_id', 'move_no']).reset_index(drop=True)\n", - "matching['move_no'] = matching['move_no'].astype(int)\n", - "matching.to_csv('../../Data/tables/matching/matching.csv')\n", - "display(matching)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# B. 5초 간격으로 이동류번호 수집" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - " 0%| | 0/17280 [00:00 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": 11, - "metadata": {}, - "outputs": [], - "source": [ - "plan = pd.read_csv('../../Data/tables/plan.csv', index_col=0)\n", - "history = pd.read_csv('../../Data/tables/history.csv', index_col=0)" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "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": 12, - "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": 13, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2024-01-05 03:20:00\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", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \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_unixdura_A1dura_A2dura_A3dura_A4dura_A5dura_A6dura_A7dura_A8dura_B1dura_B2dura_B3dura_B4dura_B5dura_B6dura_B7dura_B8cycle
601781704388800383940230000383940230000140
60201170438880024241758170002424175817000140
6020217043888003910100000039101000000140
702061704388800333526260000333526260000120
561771704388801362068260000362068260000150
............................................................
782101704392159432956220000244856220000150
841781704392160383940230000383940230000140
84201170439216024241758170002424175817000140
982061704392160333526260000333526260000120
8420217043922113910100000039101000000140
\n", - "

194 rows × 19 columns

\n", - "
" - ], - "text/plain": [ - " inter_no start_unix dura_A1 dura_A2 dura_A3 dura_A4 dura_A5 \\\n", - "60 178 1704388800 38 39 40 23 0 \n", - "60 201 1704388800 24 24 17 58 17 \n", - "60 202 1704388800 39 101 0 0 0 \n", - "70 206 1704388800 33 35 26 26 0 \n", - "56 177 1704388801 36 20 68 26 0 \n", - ".. ... ... ... ... ... ... ... \n", - "78 210 1704392159 43 29 56 22 0 \n", - "84 178 1704392160 38 39 40 23 0 \n", - "84 201 1704392160 24 24 17 58 17 \n", - "98 206 1704392160 33 35 26 26 0 \n", - "84 202 1704392211 39 101 0 0 0 \n", - "\n", - " dura_A6 dura_A7 dura_A8 dura_B1 dura_B2 dura_B3 dura_B4 dura_B5 \\\n", - "60 0 0 0 38 39 40 23 0 \n", - "60 0 0 0 24 24 17 58 17 \n", - "60 0 0 0 39 101 0 0 0 \n", - "70 0 0 0 33 35 26 26 0 \n", - "56 0 0 0 36 20 68 26 0 \n", - ".. ... ... ... ... ... ... ... ... \n", - "78 0 0 0 24 48 56 22 0 \n", - "84 0 0 0 38 39 40 23 0 \n", - "84 0 0 0 24 24 17 58 17 \n", - "98 0 0 0 33 35 26 26 0 \n", - "84 0 0 0 39 101 0 0 0 \n", - "\n", - " dura_B6 dura_B7 dura_B8 cycle \n", - "60 0 0 0 140 \n", - "60 0 0 0 140 \n", - "60 0 0 0 140 \n", - "70 0 0 0 120 \n", - "56 0 0 0 150 \n", - ".. ... ... ... ... \n", - "78 0 0 0 150 \n", - "84 0 0 0 140 \n", - "84 0 0 0 140 \n", - "98 0 0 0 120 \n", - "84 0 0 0 140 \n", - "\n", - "[194 rows x 19 columns]" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "m = 40\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", - "# 1. 조회시점의 유닉스 타임 이전의 신호이력 수집\n", - "rhistory = history.copy() # recent history\n", - "rhistory = rhistory[(rhistory.end_unix < present_time)]\n", - "# 2. 시작 유닉스 타임컬럼 생성 후 종류 유닉스 타임에서 현시별 현시기간 컬럼의 합을 뺀 값으로 입력\n", - "# - 현시시간의 합을 뺀 시간의 +- 10초 이내에 이전 주기정보가 존재하면 그 유닉스 시간을 시작 유닉스시간 값으로 하고, 존재하지 않으면 현시시간의 합을 뺀 유닉스 시간을 시작 유닉스 시간으로 지정\n", - "for i, row in rhistory.iterrows():\n", - " inter_no = row.inter_no\n", - " end_unix = row.end_unix\n", - " elapsed_time = row[[f'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]].sum() // 2 # 현시시간 합\n", - " # 이전 유닉스 존재하지 않음 : 현시시간 합의 차\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", - " # 이전 유닉스 존재, abs < 10 : 이전 유닉스\n", - " if abs(pre_unix - start_unix) < 10:\n", - " start_unix = pre_unix\n", - " # 이전 유닉스 존재, abs >=10 : 현시시간 합의 차\n", - " else:\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", - "rhistory[['inter_no', 'start_unix', 'cycle']][rhistory.inter_no==175]\n", - "rhistory = rhistory[['inter_no', 'start_unix'] + [f'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)] + ['cycle']]\n", - "rhistory\n", - "\n", - "# 2-1. 참값 판단 프로세스\n", - "hours = np.array(range(midnight, next_day + 1, 3600)) # 정각에 해당하는 시각들 목록\n", - "\n", - "def calculate_DS(rhist, curr_unix):\n", - " ghour_lt_curr_unix = hours[hours <= curr_unix].max() # the greatest hour less than (or equal to) curr_unix\n", - " start_unixes = rhist.start_unix.unique()\n", - " start_unixes_lt_ghour = np.sort(start_unixes[start_unixes < ghour_lt_curr_unix]) # start unixes less than ghour_lt_curr_unix\n", - " # 기준유닉스(base_unix) : curr_unix보다 작은 hour 중에서 가장 큰 값으로부터 다섯 번째로 작은 start_unix\n", - " if list(start_unixes_lt_ghour):\n", - " base_unix = start_unixes_lt_ghour[-5]\n", - " # start_unixes_lt_ghour가 비었을 경우에는 맨 앞 start_unix로 base_unix를 지정\n", - " else:\n", - " base_unix = rhist.start_unix.min()\n", - " D_n = curr_unix - base_unix\n", - " S_n_durs = rhist[(rhist.start_unix > base_unix) & (rhist.start_unix <= curr_unix)] \\\n", - " [[f'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]]\n", - " S_n = S_n_durs.values.sum() // 2\n", - " return D_n, S_n\n", - "\n", - "rhists = []\n", - "for inter_no in sorted(rhistory.inter_no.unique()):\n", - " rhist = rhistory.copy()[rhistory.inter_no==inter_no]\n", - " rhist = rhist.drop_duplicates(subset=['start_unix']).reset_index(drop=True)\n", - "\n", - " # D_n 및 S_n 값 정의\n", - " rhist['D_n'] = 0 # D_n : 시간차이\n", - " rhist['S_n'] = 0 # S_n : 현시시간합\n", - " for n in range(len(rhist)):\n", - " curr_unix = rhist.iloc[n].start_unix # current start_unix\n", - " rhist.loc[n, ['D_n', 'S_n']] = calculate_DS(rhist, curr_unix)\n", - "\n", - " # 이전시각, 현재시각\n", - " prev_unix = rhist.loc[0, 'start_unix'] # previous start_unix\n", - " curr_unix = rhist.loc[1, 'start_unix'] # current start_unix\n", - "\n", - " # rhist의 마지막 행에 도달할 때까지 반복\n", - " while True:\n", - " n = rhist[rhist.start_unix==curr_unix].index[0]\n", - " cycle = rhist.loc[n, 'cycle']\n", - " D_n = rhist.loc[n, 'D_n']\n", - " S_n = rhist.loc[n, 'S_n']\n", - " # 참값인 경우\n", - " if (abs(D_n - S_n) <= 5):\n", - " pass\n", - " # 참값이 아닌 경우\n", - " else:\n", - " # 2-1-1. 결측치 처리 : 인접한 두 start_unix의 차이가 계획된 주기의 두 배보다 크면 결측이 일어났다고 판단, 신호계획의 현시시간으로 \"대체\"\n", - " if curr_unix - prev_unix >= 2 * cycle:\n", - " # prev_unix를 계획된 주기만큼 늘려가면서 한 행씩 채워나간다.\n", - " # (curr_unix와의 차이가 계획된 주기보다 작거나 같아질 때까지)\n", - " new_rows = []\n", - " while curr_unix - prev_unix > cycle:\n", - " prev_unix += cycle\n", - " # 신호 계획(prow) 불러오기\n", - " start_seconds = np.array(timetable.start_seconds)\n", - " idx = (start_seconds <= prev_unix).sum() - 1\n", - " start_hour = timetable.iloc[idx].start_hour\n", - " start_minute = timetable.iloc[idx].start_minute\n", - " prow = plan.copy()[(plan.inter_no==inter_no) & (plan.start_hour==start_hour) & (plan.start_minute==start_minute)] # planned row\n", - " # prow에서 필요한 부분을 rhist에 추가\n", - " prow['start_unix'] = prev_unix\n", - " prow = prow.drop(['start_hour', 'start_minute', 'offset'], axis=1)\n", - " cycle = prow.iloc[0].cycle\n", - " rhist = pd.concat([rhist, prow])\n", - " rhist = rhist.sort_values(by='start_unix').reset_index(drop=True)\n", - " n += 1\n", - "\n", - " # 2-1-2. 이상치 처리 : 비율에 따라 해당 행을 \"삭제\"(R_n <= 0.5) 또는 \"조정\"(R_n > 0.5)한다\n", - " R_n = (curr_unix - prev_unix) / cycle # R_n : 비율\n", - " # R_n이 0.5보다 작거나 같으면 해당 행을 삭제\n", - " if R_n <= 0.5:\n", - " rhist = rhist.drop(index=n).reset_index(drop=True)\n", - " # 행삭제에 따른 curr_unix, R_n 재정의\n", - " curr_unix = rhist.loc[n, 'start_unix']\n", - " R_n = (curr_unix - prev_unix) / cycle # R_n : 비율\n", - "\n", - " # R_n이 0.5보다 크면 해당 행 조정 (비율을 유지한 채로 현시시간 대체)\n", - " if R_n > 0.5:\n", - " # 신호 계획(prow) 불러오기\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 = plan[(plan.inter_no==inter_no) & (plan.start_hour==start_hour) & (plan.start_minute==start_minute)] # planned row\n", - " # 조정된 현시시간 (prow에 R_n을 곱하고 정수로 바꿈)\n", - " adjusted_dur = prow.copy()[[f'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]] * R_n\n", - " int_parts = adjusted_dur.iloc[0].apply(lambda x: int(x))\n", - " frac_parts = adjusted_dur.iloc[0] - int_parts\n", - " difference = round(adjusted_dur.iloc[0].sum()) - int_parts.sum()\n", - " for _ in range(difference): # 소수 부분이 가장 큰 상위 '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에 조정된 현시시간을 반영\n", - " rhist.loc[n, [f'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]] = int_parts.values\n", - " rhist.loc[n, 'cycle'] = int_parts.sum().sum() // 2\n", - "\n", - " if n == rhist.index[-1]:\n", - " break\n", - " prev_unix = curr_unix\n", - " curr_unix = rhist.loc[n+1, 'start_unix']\n", - " # rhist['start_dt'] = rhist['start_unix'].map(lambda x:datetime.fromtimestamp(x))\n", - "\n", - " # 생략해도 무방할 코드\n", - " rhist = rhist.reset_index(drop=True)\n", - " rhist = rhist.sort_values(by=['start_unix'])\n", - "\n", - " # D_n 및 S_n 값 재정의\n", - " for n in range(len(rhist)):\n", - " curr_unix = rhist.iloc[n].start_unix # current start_unix\n", - " rhist.loc[n, ['D_n', 'S_n']] = calculate_DS(rhist, curr_unix)\n", - " rhists.append(rhist)\n", - "rhists = pd.concat(rhists).sort_values(by=['start_unix','inter_no'])\n", - "rhists = rhists[rhists.start_unix >= present_time - 3600]\n", - "rhists = rhists.drop(columns=['D_n', 'S_n'])\n", - "rhists" - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - " 0%| | 0/17280 [00:00\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \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
81751184
151752273
201753361
241753462
261754452
\n", - "" - ], - "text/plain": [ - " inter_no phas_A phas_B move_A move_B\n", - "8 175 1 1 8 4\n", - "15 175 2 2 7 3\n", - "20 175 3 3 6 1\n", - "24 175 3 4 6 2\n", - "26 175 4 4 5 2" - ] - }, - "execution_count": 20, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "movements_wo_start_unix_list = [] # movements without start_unix\n", - "for inter_no in sorted(movements.inter_no.unique()):\n", - " movements_wo_start_unix = movements[movements_wo_start_unix.inter_no==inter_no]\n", - " movements_wo_start_unix = movements_wo_start_unix[['inter_no', 'phas_A', 'phas_B', 'move_A', 'move_B']]\n", - " movements_wo_start_unix = movements_wo_start_unix.drop_duplicates().sort_values(by=['phas_A','phas_B'])\n", - " movements_wo_start_unix_list.append(movements_wo_start_unix)\n", - "movements_wo_start_unix = pd.concat(movements_wo_start_unix_list)\n", - "movements_wo_start_unix.head()" - ] - }, - { - "cell_type": "code", - "execution_count": 67, - "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_unixphas_Aphas_Bduration
017817043888001138
117817043888002239
217817043888003340
317817043888004423
420117043888001124
..................
76720617043921602235
76820617043921603326
76920617043921604426
77020217043922111139
771202170439221122101
\n", - "

772 rows × 5 columns

\n", - "
" - ], - "text/plain": [ - " inter_no start_unix phas_A phas_B duration\n", - "0 178 1704388800 1 1 38\n", - "1 178 1704388800 2 2 39\n", - "2 178 1704388800 3 3 40\n", - "3 178 1704388800 4 4 23\n", - "4 201 1704388800 1 1 24\n", - ".. ... ... ... ... ...\n", - "767 206 1704392160 2 2 35\n", - "768 206 1704392160 3 3 26\n", - "769 206 1704392160 4 4 26\n", - "770 202 1704392211 1 1 39\n", - "771 202 1704392211 2 2 101\n", - "\n", - "[772 rows x 5 columns]" - ] - }, - "execution_count": 67, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# 계층화된 형태로 변환\n", - "hrhists = [] # hierarchied recent history\n", - "for i, row in rhists.iterrows():\n", - " inter_no = row.inter_no\n", - " start_unix = row.start_unix\n", - "\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", - " phas_As = [isplit[j][0] for j in isplit.keys()]\n", - " phas_Bs = [isplit[j][1] for j in isplit.keys()]\n", - " durs_A = row[[f'dura_A{j}' for j in range(1,9)]]\n", - " durs_B = row[[f'dura_B{j}' for j in range(1,9)]]\n", - " durations = []\n", - " for j in range(1, len(isplit)+1):\n", - " ja = isplit[j][0]\n", - " jb = isplit[j][1]\n", - " if ja == jb:\n", - " durations.append(min(durs_A[ja-1], durs_B[jb-1]))\n", - " else:\n", - " durations.append(abs(durs_A[ja-1] - durs_B[ja-1]))\n", - " new_rows = pd.DataFrame({'inter_no':[inter_no] * len(durations), 'start_unix':[start_unix] * len(durations),\n", - " 'phas_A':phas_As, 'phas_B':phas_Bs, 'duration':durations})\n", - " hrhists.append(new_rows)\n", - "hrhists = pd.concat(hrhists)\n", - "hrhists = hrhists.sort_values(by = ['start_unix', 'inter_no', 'phas_A', 'phas_B']).reset_index(drop=True)\n", - "hrhists" - ] - }, - { - "cell_type": "code", - "execution_count": 133, - "metadata": {}, - "outputs": [], - "source": [ - "movement = time2movement[present_time]" - ] - }, - { - "cell_type": "code", - "execution_count": 138, - "metadata": {}, - "outputs": [], - "source": [ - "# 중복을 제거하고 (inter_no, start_unix) 쌍을 만듭니다.\n", - "hrhists_inter_unix = set(hrhists[['inter_no', 'start_unix']].drop_duplicates().itertuples(index=False, name=None))\n", - "movement_inter_unix = set(movement[['inter_no', 'start_unix']].drop_duplicates().itertuples(index=False, name=None))\n", - "\n", - "# hrhists에는 있지만 movement에는 없는 (inter_no, start_unix) 쌍을 찾습니다.\n", - "missing_in_movement = hrhists_inter_unix - movement_inter_unix\n", - "\n", - "# 새로운 행들을 생성합니다.\n", - "new_rows = []\n", - "for inter_no, start_unix in missing_in_movement:\n", - " # movements_wo_start_unix에서 해당 inter_no의 데이터를 찾습니다.\n", - " new_row = movements_wo_start_unix[movements_wo_start_unix['inter_no'] == inter_no].copy()\n", - " # start_unix 값을 설정합니다.\n", - " new_row['start_unix'] = start_unix\n", - " new_rows.append(new_row)\n", - "\n", - "# 새로운 데이터프레임을 생성하고 기존 movement 데이터프레임과 합칩니다.\n", - "new_movement = pd.concat(new_rows, ignore_index=True)\n", - "movement_updated = pd.concat([movement, new_movement], ignore_index=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 143, - "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", - "
inter_nonode_idstart_unixphas_Aphas_Bdurationinc_edge_Aout_edge_Ainc_edge_Bout_edge_B
0177i217043888011136-571542809_01571542811_01571542811_02571542809_01
1177i217043888012220571542811_02571542107_01-571542809_01571542809_01
2177i217043888013368NaNNaNNaNNaN
3177i217043888014426-571542809_01571542811_01571542107_02571542809_01
4176i117043888501137-571542810_01-571542797_02.99571542797_02.99571542810_01
.................................
748206i717043921602235NaNNaNNaNNaN
749206i717043921603326-571511538_02571542073_02571542073_01571511538_02
750206i717043921604426NaNNaNNaNNaN
751202i917043922111139571510152_02-571510152_01571510152_01571510152_01.65
752202i9170439221122101NaNNaNNaNNaN
\n", - "

757 rows × 10 columns

\n", - "
" - ], - "text/plain": [ - " inter_no node_id start_unix phas_A phas_B duration inc_edge_A \\\n", - "0 177 i2 1704388801 1 1 36 -571542809_01 \n", - "1 177 i2 1704388801 2 2 20 571542811_02 \n", - "2 177 i2 1704388801 3 3 68 NaN \n", - "3 177 i2 1704388801 4 4 26 -571542809_01 \n", - "4 176 i1 1704388850 1 1 37 -571542810_01 \n", - ".. ... ... ... ... ... ... ... \n", - "748 206 i7 1704392160 2 2 35 NaN \n", - "749 206 i7 1704392160 3 3 26 -571511538_02 \n", - "750 206 i7 1704392160 4 4 26 NaN \n", - "751 202 i9 1704392211 1 1 39 571510152_02 \n", - "752 202 i9 1704392211 2 2 101 NaN \n", - "\n", - " out_edge_A inc_edge_B out_edge_B \n", - "0 571542811_01 571542811_02 571542809_01 \n", - "1 571542107_01 -571542809_01 571542809_01 \n", - "2 NaN NaN NaN \n", - "3 571542811_01 571542107_02 571542809_01 \n", - "4 -571542797_02.99 571542797_02.99 571542810_01 \n", - ".. ... ... ... \n", - "748 NaN NaN NaN \n", - "749 571542073_02 571542073_01 571511538_02 \n", - "750 NaN NaN NaN \n", - "751 -571510152_01 571510152_01 571510152_01.65 \n", - "752 NaN NaN NaN \n", - "\n", - "[757 rows x 10 columns]" - ] - }, - "execution_count": 143, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "movedur = pd.merge(movement_updated, hrhists, how='inner', on=['inter_no', 'start_unix', 'phas_A', 'phas_B']) # 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", - "\n", - "# 이동류 매칭 테이블에서 진입id, 진출id를 가져와서 붙임.\n", - "for i, row in movedur.iterrows():\n", - " inter_no = row.inter_no\n", - " start_unix = row.start_unix\n", - " # incoming and outgoing edges A\n", - " move_A = row.move_A\n", - " if move_A in [17, 18]:\n", - " inc_edge_A = np.nan\n", - " out_edge_A = np.nan\n", - " else:\n", - " match_A = matching[(matching.inter_no == inter_no) & (matching.move_no == move_A)].iloc[0]\n", - " inc_edge_A = match_A.inc_edge\n", - " out_edge_A = match_A.out_edge\n", - " movedur.loc[i, ['inc_edge_A', 'out_edge_A']] = [inc_edge_A, out_edge_A]\n", - " # incoming and outgoing edges B\n", - " move_B = row.move_B\n", - " if move_B in [17, 18]:\n", - " inc_edge_B = np.nan\n", - " out_edge_B = np.nan\n", - " else:\n", - " match_B = matching[(matching.inter_no == inter_no) & (matching.move_no == move_B)].iloc[0]\n", - " inc_edge_B = match_B.inc_edge\n", - " out_edge_B = match_B.out_edge\n", - " movedur.loc[i, ['inc_edge_B', 'out_edge_B']] = [inc_edge_B, out_edge_B]\n", - "\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", - "histid['node_id'] = histid['inter_no'].map(inter2node)\n", - "histid = histid[['inter_no', 'node_id', 'start_unix', 'phas_A', 'phas_B', 'duration', 'inc_edge_A', 'out_edge_A', 'inc_edge_B', 'out_edge_B']]\n", - "histid = histid[histid.start_unix > present_time - 3600]\n", - "histid" - ] - }, - { - "cell_type": "code", - "execution_count": 71, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2024-01-05 16:40:00\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", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \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_nonode_idstart_unixphas_Aphas_Bdurationinc_edge_Aout_edge_Ainc_edge_Bout_edge_B
0202i917044368101146571510152_02-571510152_01571510152_01571510152_01.65
1202i9170443681022114NaNNaNNaNNaN
2178i317044368601138571540304_02571556450_01571556450_02571540304_01
3178i317044368602239571556450_02571500475_01571540304_02571540303_01
4178i317044368603343571540303_02.21571556450_01571540303_02.21571500475_01
.................................
477202i9170444017122114NaNNaNNaNNaN
478206i717044401711145-571511538_02571542073_02571542073_01571511538_02
479206i717044401712253NaNNaNNaNNaN
480206i717044401713326-571511538_02571542073_02571542073_01571511538_02
481206i717044401714426NaNNaNNaNNaN
\n", - "

482 rows × 10 columns

\n", - "
" - ], - "text/plain": [ - " inter_no node_id start_unix phas_A phas_B duration inc_edge_A \\\n", - "0 202 i9 1704436810 1 1 46 571510152_02 \n", - "1 202 i9 1704436810 2 2 114 NaN \n", - "2 178 i3 1704436860 1 1 38 571540304_02 \n", - "3 178 i3 1704436860 2 2 39 571556450_02 \n", - "4 178 i3 1704436860 3 3 43 571540303_02.21 \n", - ".. ... ... ... ... ... ... ... \n", - "477 202 i9 1704440171 2 2 114 NaN \n", - "478 206 i7 1704440171 1 1 45 -571511538_02 \n", - "479 206 i7 1704440171 2 2 53 NaN \n", - "480 206 i7 1704440171 3 3 26 -571511538_02 \n", - "481 206 i7 1704440171 4 4 26 NaN \n", - "\n", - " out_edge_A inc_edge_B out_edge_B \n", - "0 -571510152_01 571510152_01 571510152_01.65 \n", - "1 NaN NaN NaN \n", - "2 571556450_01 571556450_02 571540304_01 \n", - "3 571500475_01 571540304_02 571540303_01 \n", - "4 571556450_01 571540303_02.21 571500475_01 \n", - ".. ... ... ... \n", - "477 NaN NaN NaN \n", - "478 571542073_02 571542073_01 571511538_02 \n", - "479 NaN NaN NaN \n", - "480 571542073_02 571542073_01 571511538_02 \n", - "481 NaN NaN NaN \n", - "\n", - "[482 rows x 10 columns]" - ] - }, - "execution_count": 71, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "m = 200\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", - "# (구) make_rhistory\n", - "Rhists = [] # Recent history (1시간 이내)\n", - "for inter_no in history.inter_no.unique():\n", - " # - 5분마다 신호이력 데이터 수집해서 통합테이블 생성할때\n", - " # 1. 조회시점의 유닉스 타임 이전의 신호이력 수집\n", - " rhistory = history.copy() # recent history\n", - " rhistory = rhistory[(rhistory.end_unix < present_time)]\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 = plan[(plan.inter_no==inter_no) & (plan.start_hour==start_hour) & (plan.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", - " 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 - 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'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]]\n", - " # S_n : 현시시간합\n", - " S_n = ddurations.values.sum() // 2\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'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]]\n", - " S_n = ddurations.values.sum() // 2\n", - " # 비율이 0.5보다 작거나 같으면 해당 행을 삭제\n", - " if (abs(D_n - S_n) > 10) & (R_n <= 0.5):\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'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]]\n", - " S_n = ddurations.values.sum() // 2\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 = plan[(plan.inter_no==inter_no) & (plan.start_hour==start_hour) & (plan.start_minute==start_minute)].copy().reset_index(drop=True).iloc[0] # planned row\n", - " adjusted_dur = prow[[f'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]] * 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, [f'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]] = int_parts.values\n", - " Rhist.loc[n, 'cycle'] = int_parts.sum() // 2\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", - "\n", - "# (구) make_histid\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'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]].sum() // 2 # 현시시간 합\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", - "rhistory = rhistory[['inter_no', 'start_unix'] + [f'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)] + ['cycle']]\n", - "\n", - "# 계층화된 형태로 변환\n", - "hrhistory = [] # hierarchized recent history\n", - "for i, row in rhistory.iterrows():\n", - " inter_no = row.inter_no\n", - " start_unix = row.start_unix\n", - "\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", - " phas_As = [isplit[j][0] for j in isplit.keys()]\n", - " phas_Bs = [isplit[j][1] for j in isplit.keys()]\n", - " durs_A = row[[f'dura_A{j}' for j in range(1,9)]]\n", - " durs_B = row[[f'dura_B{j}' for j in range(1,9)]]\n", - " durations = []\n", - " for j in range(1, len(isplit)+1):\n", - " ja = isplit[j][0]\n", - " jb = isplit[j][1]\n", - " if ja == jb:\n", - " durations.append(min(durs_A[ja-1], durs_B[jb-1]))\n", - " else:\n", - " durations.append(abs(durs_A[ja-1] - durs_B[ja-1]))\n", - " new_rows = pd.DataFrame({'inter_no':[inter_no] * len(durations), 'start_unix':[start_unix] * len(durations),\n", - " 'phas_A':phas_As, 'phas_B':phas_Bs, 'duration':durations})\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']) # 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", - "\n", - "# 이동류 매칭 테이블에서 진입id, 진출id를 가져와서 붙임.\n", - "for i, row in movedur.iterrows():\n", - " inter_no = row.inter_no\n", - " start_unix = row.start_unix\n", - " # incoming and outgoing edges A\n", - " move_A = row.move_A\n", - " if move_A in [17, 18]:\n", - " inc_edge_A = np.nan\n", - " out_edge_A = np.nan\n", - " else:\n", - " match_A = matching[(matching.inter_no == inter_no) & (matching.move_no == move_A)].iloc[0]\n", - " inc_edge_A = match_A.inc_edge\n", - " out_edge_A = match_A.out_edge\n", - " movedur.loc[i, ['inc_edge_A', 'out_edge_A']] = [inc_edge_A, out_edge_A]\n", - " # incoming and outgoing edges B\n", - " move_B = row.move_B\n", - " if move_B in [17, 18]:\n", - " inc_edge_B = np.nan\n", - " out_edge_B = np.nan\n", - " else:\n", - " match_B = matching[(matching.inter_no == inter_no) & (matching.move_no == move_B)].iloc[0]\n", - " inc_edge_B = match_B.inc_edge\n", - " out_edge_B = match_B.out_edge\n", - " movedur.loc[i, ['inc_edge_B', 'out_edge_B']] = [inc_edge_B, out_edge_B]\n", - "\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", - "histid['node_id'] = histid['inter_no'].map(inter2node)\n", - "histid = histid[['inter_no', 'node_id', 'start_unix', 'phas_A', 'phas_B', 'duration', 'inc_edge_A', 'out_edge_A', 'inc_edge_B', 'out_edge_B']]\n", - "histid = histid[histid.start_unix > present_time - 3600]\n", - "# 시뮬레이션 시작시각 : 현재시각 - 600\n", - "# 시뮬레이션 종료시각 : 현재시각 - 300\n", - "# 현재시각 : present_time, PT\n", - "# PT-900 ... PT-600 ... PT-300 ... PT\n", - "histid" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2024-01-05 04:10:00\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", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \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_nonode_idstart_unixphas_Aphas_Bdurationinc_edge_Aout_edge_Ainc_edge_Bout_edge_B
0176i117043918501137-571542810_01-571542797_02.99571542797_02.99571542810_01
1176i117043918502273-571542810_01-571542797_02.99-571542810_01571543469_01
2176i117043918503340571543469_02-571542797_02.99NaNNaN
3178i317043918801138571540304_02571556450_01571556450_02571540304_01
4178i317043918802239571556450_02571500475_01571540304_02571540303_01
.................................
528201i817043952501124-571500569_01571500583_02-571500569_01571500618_01
529201i817043952502224571500618_02571500583_02571500618_02571500617_01
530201i817043952503317571500617_02571500618_01571500618_02571500617_01
531201i817043952504458571500617_02571500618_01571500617_02571500569_01
532201i817043952505517571500583_01571500617_01571500583_01571500569_01
\n", - "

533 rows × 10 columns

\n", - "
" - ], - "text/plain": [ - " inter_no node_id start_unix phas_A phas_B duration inc_edge_A \\\n", - "0 176 i1 1704391850 1 1 37 -571542810_01 \n", - "1 176 i1 1704391850 2 2 73 -571542810_01 \n", - "2 176 i1 1704391850 3 3 40 571543469_02 \n", - "3 178 i3 1704391880 1 1 38 571540304_02 \n", - "4 178 i3 1704391880 2 2 39 571556450_02 \n", - ".. ... ... ... ... ... ... ... \n", - "528 201 i8 1704395250 1 1 24 -571500569_01 \n", - "529 201 i8 1704395250 2 2 24 571500618_02 \n", - "530 201 i8 1704395250 3 3 17 571500617_02 \n", - "531 201 i8 1704395250 4 4 58 571500617_02 \n", - "532 201 i8 1704395250 5 5 17 571500583_01 \n", - "\n", - " out_edge_A inc_edge_B out_edge_B \n", - "0 -571542797_02.99 571542797_02.99 571542810_01 \n", - "1 -571542797_02.99 -571542810_01 571543469_01 \n", - "2 -571542797_02.99 NaN NaN \n", - "3 571556450_01 571556450_02 571540304_01 \n", - "4 571500475_01 571540304_02 571540303_01 \n", - ".. ... ... ... \n", - "528 571500583_02 -571500569_01 571500618_01 \n", - "529 571500583_02 571500618_02 571500617_01 \n", - "530 571500618_01 571500618_02 571500617_01 \n", - "531 571500618_01 571500617_02 571500569_01 \n", - "532 571500617_01 571500583_01 571500569_01 \n", - "\n", - "[533 rows x 10 columns]" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "make_histid(50)" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "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", - "
inter_noend_unixdura_A1dura_A2dura_A3dura_A4dura_A5dura_A6dura_A7dura_A8...dura_B3dura_B4dura_B5dura_B6dura_B7dura_B8cycleoffsetD_nS_n
0202170438054039101000000...00000014010300
1202170438068039101000000...00000014010300
2202170438082039101000000...00000014010300
3202170438096039101000000...00000014010300
4202170438110039101000000...00000014010300
..................................................................
200202170440967946114000000...00000016010300
201202170440984046114000000...00000016010300
202202170441000046114000000...00000016010300
203202170441016046114000000...00000016010300
204202170441032046114000000...00000016010300
\n", - "

205 rows × 22 columns

\n", - "
" - ], - "text/plain": [ - " inter_no end_unix dura_A1 dura_A2 dura_A3 dura_A4 dura_A5 \\\n", - "0 202 1704380540 39 101 0 0 0 \n", - "1 202 1704380680 39 101 0 0 0 \n", - "2 202 1704380820 39 101 0 0 0 \n", - "3 202 1704380960 39 101 0 0 0 \n", - "4 202 1704381100 39 101 0 0 0 \n", - ".. ... ... ... ... ... ... ... \n", - "200 202 1704409679 46 114 0 0 0 \n", - "201 202 1704409840 46 114 0 0 0 \n", - "202 202 1704410000 46 114 0 0 0 \n", - "203 202 1704410160 46 114 0 0 0 \n", - "204 202 1704410320 46 114 0 0 0 \n", - "\n", - " dura_A6 dura_A7 dura_A8 ... dura_B3 dura_B4 dura_B5 dura_B6 \\\n", - "0 0 0 0 ... 0 0 0 0 \n", - "1 0 0 0 ... 0 0 0 0 \n", - "2 0 0 0 ... 0 0 0 0 \n", - "3 0 0 0 ... 0 0 0 0 \n", - "4 0 0 0 ... 0 0 0 0 \n", - ".. ... ... ... ... ... ... ... ... \n", - "200 0 0 0 ... 0 0 0 0 \n", - "201 0 0 0 ... 0 0 0 0 \n", - "202 0 0 0 ... 0 0 0 0 \n", - "203 0 0 0 ... 0 0 0 0 \n", - "204 0 0 0 ... 0 0 0 0 \n", - "\n", - " dura_B7 dura_B8 cycle offset D_n S_n \n", - "0 0 0 140 103 0 0 \n", - "1 0 0 140 103 0 0 \n", - "2 0 0 140 103 0 0 \n", - "3 0 0 140 103 0 0 \n", - "4 0 0 140 103 0 0 \n", - ".. ... ... ... ... ... ... \n", - "200 0 0 160 103 0 0 \n", - "201 0 0 160 103 0 0 \n", - "202 0 0 160 103 0 0 \n", - "203 0 0 160 103 0 0 \n", - "204 0 0 160 103 0 0 \n", - "\n", - "[205 rows x 22 columns]" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "m = 100\n", - "fmins = range(midnight, next_day, 300) # fmins : unix time by Five MINuteS\n", - "present_time = fmins[m] # 현재시점\n", + "def make_match1():\n", + " '''\n", + " 설명 :\n", + " 신호 DB에는 매 초마다 이동류정보가 업데이트 된다. 그리고 이 이동류정보를 매 5초마다 불러와서 사용하게 된다.\n", + " '../../Data/tables/moves/'에는 5초마다의 이동류정보가 저장되어 있다.\n", "\n", - "# 1. 신호이력 데이터 수집\n", - "rhistory = history.copy()[(history.end_unix < present_time)]\n", - "rhistory = rhistory.reset_index(drop=True)\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", - "rhist['D_n'] = 0 # D_n : 시간차이\n", - "rhist['S_n'] = 0 # S_n : 현시시간합\n", - "rhist" + " return : 통합된 이동류정보\n", + " - 모든 inter_no(교차로번호)에 대한 A, B링 현시별 이동류정보\n", + " '''\n", + " # [이동류번호] 불러오기 (약 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.to_csv(path_moves + \"match1.csv\")\n", + " return match1" ] }, { "cell_type": "code", - "execution_count": 43, + "execution_count": 3, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2024-01-05 08:19:00\n", - "2024-01-05 07:20:20\n" - ] - } - ], + "outputs": [], "source": [ - "movement = time2movement[present_time]\n", - "max_unix = movement.start_unix.max()\n", - "min_unix = movement.start_unix.min()\n", - "print(datetime.fromtimestamp(max_unix))\n", - "print(datetime.fromtimestamp(min_unix))" + "def make_match2(match1):\n", + " '''\n", + " match1을 계층화함.\n", + " - match1의 컬럼 : inter_no, phas_A, phas_B, move_A, move_B\n", + " - match2의 컬럼 : inter_no, phase_no, ring_type, move_no\n", + " '''\n", + " # 계층화 (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", + " return match2" ] }, { "cell_type": "code", - "execution_count": 25, + "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", - "
inter_nophas_Aphas_Bmove_Amove_Bstart_unix
020111831704406820
120122521704406820
220133621704406820
320144611704406820
420155741704406820
.....................
59820211621704410320
5992022217181704410320
60020111831704410340
60120122521704410340
60220155741704410340
\n", - "

603 rows × 6 columns

\n", - "
" - ], - "text/plain": [ - " inter_no phas_A phas_B move_A move_B start_unix\n", - "0 201 1 1 8 3 1704406820\n", - "1 201 2 2 5 2 1704406820\n", - "2 201 3 3 6 2 1704406820\n", - "3 201 4 4 6 1 1704406820\n", - "4 201 5 5 7 4 1704406820\n", - ".. ... ... ... ... ... ...\n", - "598 202 1 1 6 2 1704410320\n", - "599 202 2 2 17 18 1704410320\n", - "600 201 1 1 8 3 1704410340\n", - "601 201 2 2 5 2 1704410340\n", - "602 201 5 5 7 4 1704410340\n", - "\n", - "[603 rows x 6 columns]" - ] - }, - "execution_count": 25, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], + "source": [ + "def make_match3(match2):\n", + " '''\n", + " 각 movement들에 방향(진입방향, 진출방향)을 매칭시켜 추가함.\n", + " - match2의 컬럼 : inter_no, phase_no, ring_type, move_no\n", + " - match3의 컬럼 : inter_no, phase_no, ring_type, move_no, inc_dir, out_dir\n", + "\n", + " nema : \n", + " - 컬럼 : move_no, inc_dir, out_dir\n", + " - 모든 종류의 이동류번호에 대하여 진입방향과 진출방향을 매칭시키는 테이블\n", + " - 이동류번호 : 1 ~ 16, 17, 18, 21\n", + " - 진입, 진출방향(8방위) : 동, 서, 남, 북, 북동, 북서, 남동, 남서\n", + " '''\n", + " # 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", + " return match3" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], "source": [ - "fmins = range(midnight, next_day, 300) # fmins : unix time by Five MINuteS\n", - "present_time = fmins[m] # 현재시점\n", - "print(datetime.fromtimestamp(present_time))\n", + "def make_match4(match3):\n", + " '''\n", + " 방위각 정보를 매칭시켜 추가함.\n", + " - match3의 컬럼 : inter_no, phase_no, ring_type, move_no, inc_dir, out_dir\n", + " - match4의 컬럼 : inter_no, phase_no, ring_type, move_no, inc_dir, out_dir, inc_angle, out_angle\n", + "\n", + " angle_original : \n", + " - 컬럼 : inter_no, angle_Aj, angle_Bj (j : 1 ~ 8)\n", + " - 모든 종류의 이동류번호에 대하여 진입방향과 진출방향을 매칭시키는 테이블\n", + " - 이동류번호 : 1 ~ 16, 17, 18, 21\n", + " - 진입, 진출방향(8방위) : 동, 서, 남, 북, 북동, 북서, 남동, 남서\n", + " '''\n", "\n", - "Rhists = [] # Recent history (1시간 이내)\n", - "for inter_no in history.inter_no.unique():\n", - " # - 5분마다 신호이력 데이터 수집해서 통합테이블 생성할때\n", - " # 1. 조회시점의 유닉스 타임을 기준으로 신호이력의 유닉스 타임이 1시간 이내인(Rhist) 데이터 수집\n", - " rhistory = history.copy() # recent history\n", - " rhistory = rhistory[(rhistory.end_unix < present_time)]\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 = plan[(plan.inter_no==inter_no) & (plan.start_hour==start_hour) & (plan.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", - " rhist = pd.concat([rhist] + new_rows).sort_values(['end_unix'])\n", - " rhist = rhist.reset_index(drop=True)\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", + " # 계층화\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", + " # 병합\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", + " return match4" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "def make_match5(match4):\n", + " '''\n", + " 진입엣지id, 진출엣지id, 노드id를 추가함 (주교차로).\n", + " - match4의 컬럼 : inter_no, phase_no, ring_type, move_no, inc_dir, out_dir, inc_angle, out_angle\n", + " - match5의 컬럼 : inter_no, phase_no, ring_type, move_no, inc_dir, out_dir, inc_angle, out_angle, inc_edge, out_edge, node_id\n", + " \n", + " 사용된 데이터 : \n", + " (1) net\n", + " - 성남시 정자동 부근의 샘플 네트워크\n", + " (2) inter_node\n", + " - 교차로번호와 노드id를 매칭시키는 테이블.\n", + " - parent/child 정보도 포함되어 있음\n", + " - 컬럼 : inter_no, node_id, inter_type\n", + " (3) inter_info\n", + " - 교차로 정보. 여기에서는 위도와 경도가 쓰임.\n", + " - 컬럼 : inter_no, inter_name, inter_lat, inter_lon, group_no, main_phase_no\n", + "\n", + " 진입엣지id, 진출엣지id를 얻는 과정 :\n", + " - match5 = match4.copy()의 각 열을 순회하면서 아래 과정을 반복함.\n", + " * 진입에 대해서만 서술하겠지만 진출도 마찬가지로 설명될 수 있음\n", + " - 해당 행의 교차로정보로부터 노드ID를 얻어내고, 해당 노드에 대한 모든 진출엣지id를 inc_edges에 저장.\n", + " * inc_edge(진입엣지) : incoming edge, out_edge(진출엣지) : outgoing_edge\n", + " - inc_edges의 모든 진입엣지에 대하여 진입방향(inc_dires, 2차원 단위벡터)을 얻어냄.\n", + " - 해당 행의 진입각으로부터 그에 대응되는 진입각방향(단위벡터)를 얻어냄.\n", + " - 주어진 진입각방향에 대하여 내적이 가장 작은 진입방향에 대한 진입엣지를 inc_edge_id로 지정함.\n", + " '''\n", "\n", - " # 1-2. 이상치 처리 : 기준유닉스로부터의 시간차이와 현시시간합이 11 이상 차이나면 이상치가 발생했다고 판단\n", - " Rhist = rhist.copy() # recent history 1704393231\n", - " Rhist = Rhist[(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'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]]\n", - " # S_n : 현시시간합\n", - " S_n = ddurations.values.sum() // 2\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'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]]\n", - " S_n = ddurations.values.sum() // 2\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'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]]\n", - " S_n = ddurations.values.sum() // 2\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 = plan[(plan.inter_no==inter_no) & (plan.start_hour==start_hour) & (plan.start_minute==start_minute)].copy().reset_index(drop=True).iloc[0] # planned row\n", - " adjusted_dur = prow[[f'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]] * 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, [f'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]] = int_parts.values\n", - " Rhist.loc[n, 'cycle'] = int_parts.sum() // 2\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", + " net = sumolib.net.readNet('../../Data/networks/SN_sample.net.xml')\n", + " # 교차로-노드 매칭 정보 불러오기\n", + " inter_node = pd.read_csv('../../Data/tables/inter_node.csv', index_col=0)\n", + " # 교차로정보(위, 경도) 불러오기\n", + " inter_info = pd.read_csv('../../Data/tables/inter_info.csv', index_col=0)\n", + "\n", + " # parent node만 가져옴.\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.sort_values(by=['inter_no','phase_no','ring_type']).reset_index(drop=True)\n", + " return match5" ] }, { "cell_type": "code", - "execution_count": 16, + "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", - "
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": 16, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "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", + "def make_match6(match5):\n", + " '''\n", + " 진입엣지id, 진출엣지id, 노드id를 추가함 (부교차로).\n", + " - match6의 컬럼 : inter_no, phase_no, ring_type, move_no, inc_dir, out_dir, inc_angle, out_angle, inc_edge, out_edge, node_id\n", + " \n", + " 사용된 데이터 : \n", + " (1) inter_node\n", + " - 교차로번호와 노드id를 매칭시키는 테이블.\n", + " - parent/child 정보도 포함되어 있음\n", + " - 컬럼 : inter_no, node_id, inter_type\n", + " (2) uturn (유턴정보)\n", + " - 컬럼 : parent_id, child_id, direction, condition, inc_edge, out_edge\n", + " - parent_id, child_id : 주교차로id, 유턴교차로id\n", + " - direction : 주교차로에 대한 유턴노드의 상대적인 위치(방향)\n", + " - condition : 좌회전시, 직진시, 직좌시, 보행신호시 중 하나\n", + " - inc_edge, out_edge : 유턴에 대한 진입진출엣지\n", + " (3) coord (연동교차로정보)\n", + " - 컬럼 : parent_id, child_id, phase_no, ring_type, inc_edge, out_edge\n", + " - parent_id, child_id : 주교차로id, 연동교차로id\n", + " - 나머지 컬럼 : 각 (현시, 링)별 진입진출엣지\n", + "\n", + " 설명 :\n", + " - match5는 주교차로에 대해서만 진입엣지id, 진출엣지id, 노드id를 추가했었음.\n", + " 여기에서 uturn, coord를 사용해서 부교차로들(유턴교차로, 연동교차로)에 대해서도 해당 값들을 부여함.\n", + " 유턴교차로 :\n", + " - directions를 정북기준 시계방향의 8방위로 정함.\n", + " - 이를 통해 진입방향이 주어진 경우에 좌회전, 직진, 보행 등에 대한 (진입방향, 진출방향)을 얻어낼 수 있음.\n", + " - 예) 진입방향(direction)이 '북'일 때, \n", + " - 직진 : (북, 남)\n", + " * 남 : directions[(ind + 4) % len(directions)]\n", + " - 좌회전 : (북, 동)\n", + " * 동 : directions[(ind + 2) % len(directions)]\n", + " - 보행 : (서, 동)\n", + " * 서 : directions[(ind - 2) % len(directions)]\n", + " - uturn의 각 행을 순회하면서 아래 과정을 반복함\n", + " - match5에서 parent_id에 해당하는 행들을 가져옴(cmatch).\n", + " - condition 별로 진입방향, 진출방향A, 진출방향B 정함.\n", + " - 상술한 directions를 활용하여 정함.\n", + " - (진입방향, 진출방향A, 진출방향B)을 고려하여 (현시, 링) 별로 진입엣지id, 진출엣지id를 정함.\n", + " - ex) cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_A), ['inc_edge', 'out_edge']] = [inc_edge_id, out_edge_id]\n", + " - 순회하면서 만든 cmatch를 cmatchs라는 리스트에 저장함.\n", + "\n", + " 연동교차로 :\n", + " - 연동교차로의 경우 coord에 (현시, 링)별 진입엣지ID, 진출엣지ID가 명시되어 있음.\n", + " - 'inc_dir', 'out_dir', 'inc_angle','out_angle'와 같은 열들은 np.nan을 지정해놓음.\n", + " - 이 열들은, 사실상 다음 스텝부터는 사용되지 않는 열들이기 때문에 np.nan으로 지정해놓아도 문제없음.\n", + "\n", + " match6 :\n", + " - 이렇게 얻은 match5, cmatchs, coord를 모두 pd.concat하여 match6을 얻어냄.\n", + " '''\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" + " inter_node = pd.read_csv('../../Data/tables/inter_node.csv', index_col=0)\n", + " node2inter = dict(zip(inter_node['node_id'], inter_node['inter_no']))\n", + "\n", + " uturn = pd.read_csv('../../Data/tables/child_uturn.csv')\n", + " coord = pd.read_csv('../../Data/tables/child_coord.csv')\n", + " child_ids = inter_node[inter_node.inter_type=='child'].node_id.unique()\n", + " ch2pa = {} # child to parent\n", + " for child_id in child_ids:\n", + " parent_no = inter_node[inter_node.node_id==child_id].inter_no.iloc[0]\n", + " sub_inter_node = inter_node[inter_node.inter_no==parent_no]\n", + " ch2pa[child_id] = sub_inter_node[sub_inter_node.inter_type=='parent'].iloc[0].node_id\n", + " directions = ['북', '북동', '동', '남동', '남', '남서', '서', '북서'] # 정북기준 시계방향으로 8방향\n", + "\n", + " # 각 uturn node에 대하여 (inc_edge_id, out_edge_id) 부여\n", + " cmatches = []\n", + " for _, row in uturn.iterrows():\n", + " child_id = row.child_id\n", + " parent_id = row.parent_id\n", + " direction = row.direction\n", + " condition = row.condition\n", + " inc_edge_id = row.inc_edge\n", + " out_edge_id = row.out_edge\n", + " # match5에서 parent_id에 해당하는 행들을 가져옴\n", + " cmatch = match5.copy()[match5.node_id==parent_id] # match dataframe for a child node\n", + " cmatch = cmatch.sort_values(by=['phase_no', 'ring_type']).reset_index(drop=True)\n", + " cmatch['node_id'] = child_id\n", + " cmatch[['inc_edge', 'out_edge']] = np.nan\n", + "\n", + " # condition 별로 inc_dire, out_dire_A, out_dire_B를 정함\n", + " ind = directions.index(direction)\n", + " if condition == \"좌회전시\":\n", + " inc_dire = direction\n", + " out_dire_A = out_dire_B = directions[(ind + 2) % len(directions)]\n", + " elif condition == \"직진시\":\n", + " inc_dire = direction\n", + " out_dire_A = out_dire_B = directions[(ind + 4) % len(directions)]\n", + " elif condition == \"직좌시\":\n", + " inc_dire = direction\n", + " out_dire_A = directions[(ind + 2) % len(directions)]\n", + " out_dire_B = directions[(ind + 4) % len(directions)]\n", + " elif condition == \"보행신호시\":\n", + " inc_dire = directions[(ind + 2) % len(directions)]\n", + " out_dire_A = directions[(ind - 2) % len(directions)]\n", + " out_dire_B = directions[(ind - 2) % len(directions)]\n", + "\n", + " # (inc_dire, out_dire_A, out_dire_B) 별로 inc_edge_id, out_edge_id를 정함\n", + " if condition == '직좌시':\n", + " ap = cmatch[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_A)].phase_no.iloc[0]\n", + " bp = cmatch[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_B)].phase_no.iloc[0]\n", + " # 직진과 좌회전이 같은 현시에 있는 경우에만 (inc_edge_id, out_edge_id)를 부여한다.\n", + " if ap == bp:\n", + " cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_A), ['inc_edge', 'out_edge']] = [inc_edge_id, out_edge_id]\n", + " cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_B), ['inc_edge', 'out_edge']] = [inc_edge_id, out_edge_id]\n", + " elif condition == '보행신호시':\n", + " cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_A), ['inc_edge', 'out_edge']] = [inc_edge_id, out_edge_id]\n", + " cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_B), ['inc_edge', 'out_edge']] = [inc_edge_id, out_edge_id]\n", + " # 이동류번호가 17(보행신호)이면서 유턴노드방향으로 가는 신호가 없으면 (inc_edge_id, out_edge_id)를 부여한다.\n", + " cmatch.loc[(cmatch.move_no==17) & (cmatch.out_dir!=direction), ['inc_edge', 'out_edge']] = [inc_edge_id, out_edge_id]\n", + " else: # '직진시', '좌회전시'\n", + " cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_A), ['inc_edge', 'out_edge']] = [inc_edge_id, out_edge_id]\n", + " cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_B), ['inc_edge', 'out_edge']] = [inc_edge_id, out_edge_id]\n", + " # 유턴신호의 이동류번호를 19로 부여한다.\n", + " cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_A), 'move_no'] = 19\n", + " cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_B), 'move_no'] = 19\n", + " cmatches.append(cmatch)\n", + "\n", + " # 각 coordination node에 대하여 (inc_edge_id, out_edge_id) 부여\n", + " coord['inter_no'] = coord['parent_id'].map(node2inter)\n", + " coord = coord.rename(columns={'child_id':'node_id'})\n", + " coord[['inc_dir', 'out_dir', 'inc_angle','out_angle']] = np.nan\n", + " coord['move_no'] = 20\n", + " coord = coord[['inter_no', 'phase_no', 'ring_type', 'move_no', 'inc_dir', 'out_dir', 'inc_angle','out_angle', 'inc_edge', 'out_edge', 'node_id']]\n", + " \n", + " # display(coord)\n", + " cmatches = pd.concat(cmatches)\n", + " match6 = pd.concat([match5, cmatches, coord]).drop_duplicates().sort_values(by=['inter_no', 'node_id', 'phase_no', 'ring_type'])\n", + " # with pd.option_context('display.max_rows', None, 'display.max_columns', None):\n", + " match6.to_csv('../../Data/tables/matching/match6.csv')\n", + " return match6" ] }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 8, "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", - " + fmins[m-2] : 시뮬레이션 시작시점\n", - " + fmins[m-1] : 시뮬레이션 종료시점\n", - " output : rhistory\n", - " - recent history\n", - " - 현재시각(present_time) 이전 1시간 동안의 신호이력에 대하여 결측치 및 이상치를 처리한 결과\n", - " - 교차로번호(inter_no), 종료유닉스(end_unix), 현시시간(dur_Aj, dur_Bj), 주기(cycle), 옵셋(offset)\n", + "def make_matching(match6):\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 = [] # Recent history (1시간 이내)\n", - " for inter_no in history.inter_no.unique():\n", - " # - 5분마다 신호이력 데이터 수집해서 통합테이블 생성할때\n", - " # 1. 조회시점의 유닉스 타임을 기준으로 신호이력의 유닉스 타임이 1시간 이내인(Rhist) 데이터 수집\n", - " rhistory = history.copy() # recent history\n", - " rhistory = rhistory[(rhistory.end_unix < present_time)]\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 = plan[(plan.inter_no==inter_no) & (plan.start_hour==start_hour) & (plan.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", - " 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 - 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'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]]\n", - " # S_n : 현시시간합\n", - " S_n = ddurations.values.sum() // 2\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'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]]\n", - " S_n = ddurations.values.sum() // 2\n", - " # 비율이 0.5보다 작거나 같으면 해당 행을 삭제\n", - " if (abs(D_n - S_n) > 10) & (R_n <= 0.5):\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'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]]\n", - " S_n = ddurations.values.sum() // 2\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 = plan[(plan.inter_no==inter_no) & (plan.start_hour==start_hour) & (plan.start_minute==start_minute)].copy().reset_index(drop=True).iloc[0] # planned row\n", - " adjusted_dur = prow[[f'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]] * 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, [f'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]] = int_parts.values\n", - " Rhist.loc[n, 'cycle'] = int_parts.sum() // 2\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" + " 이동류 매칭 : 각 교차로에 대하여, 가능한 모든 이동류 (1~18, 21)에 대한 진입·진출엣지ID를 지정한다.\n", + " 모든 이동류에 대해 지정하므로, 시차제시 이전과 다른 이동류가 등장하더라도 항상 진입·진출 엣지 ID를 지정할 수 있다. \n", + " - matching의 컬럼 : inter_no, move_no, inc_dir, out_dir, inc_edge, out_edge, node_id\n", + " \n", + " 설명 : \n", + " - 필요한 리스트, 딕셔너리 등을 정의\n", + " (1) 가능한 (진입방향, 진출방향) 목록 [리스트]\n", + " (2) 각 교차로별 방향 목록 : pdires (possible directions) [딕셔너리]\n", + " (3) 각 (교차로, 진입방향) 별 진입id 목록 : inc2id (incoming direction to incoming edge_id) [딕셔너리]\n", + " (4) 각 (교차로, 진출방향) 별 진출id 목록 : out2id (outgoing direction to outgoing edge_id) [딕셔너리]\n", + " (5) 각 교차로별 가능한 (진입방향, 진출방향) 목록 : pflow (possible flows) [딕셔너리]\n", + " - matching은 빈 리스트로 지정.\n", + " - 모든 노드id에 대하여 다음 과정을 반복\n", + " - 해당 노드id에 대한 모든 가능한 (진입방향, 진출방향)에 대하여 다음 과정을 반복\n", + " - (노드id, 진입방향)으로부터 진입엣지id를 얻어냄. 마찬가지로 진출엣지id도 얻어냄\n", + " - 얻어낸 정보를 바탕으로 한 행(new_row)을 만들고 이것을 matching에 append\n", + " '''\n", + "\n", + " match7 = match6.copy()\n", + " match7 = match7[['inter_no', 'move_no', 'inc_dir', 'out_dir', 'inc_edge', 'out_edge', 'node_id']]\n", + " inter_node = pd.read_csv('../../Data/tables/inter_node.csv', index_col=0)\n", + " nema = pd.read_csv('../../Data/tables/nema.csv', encoding='cp949')\n", + "\n", + " parent_ids = sorted(inter_node[inter_node.inter_type=='parent'].node_id.unique())\n", + " child_ids = sorted(inter_node[inter_node.inter_type=='child'].node_id.unique())\n", + "\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 node_id in parent_ids:\n", + " dires = match7[match7.node_id == node_id][['inc_dir','out_dir']].values.flatten()\n", + " dires = {dire for dire in dires if type(dire)==str}\n", + " pdires[node_id] = dires\n", + " # (3) 각 (교차로, 진입방향) 별 진입id 목록 : inc2id (incoming direction to incoming edge_id)\n", + " inc2id = {}\n", + " for node_id in parent_ids:\n", + " for inc_dir in pdires[node_id]:\n", + " df = match7[(match7.node_id==node_id) & (match7.inc_dir==inc_dir)]\n", + " inc2id[(node_id, inc_dir)] = df.inc_edge.iloc[0]\n", + " # (4) 각 (교차로, 진출방향) 별 진출id 목록 : out2id (outgoing direction to outgoing edge_id)\n", + " out2id = {}\n", + " for node_id in parent_ids:\n", + " for out_dir in pdires[node_id]:\n", + " df = match7[(match7.node_id==node_id) & (match7.out_dir==out_dir)]\n", + " out2id[(node_id, out_dir)] = df.out_edge.iloc[0]\n", + " # (5) 각 교차로별 가능한 (진입방향, 진출방향) 목록 : pflow (possible flows)\n", + " pflow = {}\n", + " for node_id in parent_ids:\n", + " pflow[node_id] = [flow for flow in flows if set(flow).issubset(pdires[node_id])]\n", + " # (6) 가능한 이동류에 대하여 진입id, 진출id 배정 : matching\n", + " node2inter = dict(zip(match7['node_id'], match7['inter_no']))\n", + " dires_right = ['북', '서', '남', '동', '북'] # ex (북, 서), (서, 남) 등은 우회전 flow\n", + " matching = []\n", + " for node_id in parent_ids:\n", + " inter_no = node2inter[node_id]\n", + " # 좌회전과 직진(1 ~ 16)\n", + " for (inc_dir, out_dir) in pflow[node_id]:\n", + " move_no = nema[(nema.inc_dir==inc_dir) & (nema.out_dir==out_dir)].move_no.iloc[0]\n", + " inc_edge = inc2id[(node_id, inc_dir)]\n", + " out_edge = out2id[(node_id, 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[node_id]):\n", + " inc_edge = inc2id[(node_id, inc_dir)]\n", + " out_edge = out2id[(node_id, 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.append(match7[match7.node_id.isin(child_ids)])\n", + " matching = pd.concat(matching)\n", + " matching = matching.dropna().sort_values(by=['inter_no', 'node_id', 'move_no']).reset_index(drop=True)\n", + " matching['move_no'] = matching['move_no'].astype(int)\n", + " matching.to_csv('../../Data/tables/matching/matching.csv')\n", + " return matching" ] }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 9, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2024-01-05 08:20:00\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", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \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_unixdura_A1dura_A2dura_A3dura_A4dura_A5dura_A6dura_A7dura_A8dura_B1dura_B2dura_B3dura_B4dura_B5dura_B6dura_B7dura_B8cycle
0201170440682030361858180003036185818000160
11771704406830402571340000402571340000170
22101704406850433965230000245865230000170
31751704406870404255330000404229590000170
417617044069103793400000037934000000170
............................................................
1461751704410269404255330000404229590000170
14717617044103103793400000037934000000170
1481781704410310383942410000383962210000160
14920217044103204611400000046114000000160
150201170441034030361858180003036185818000160
\n", - "

151 rows × 19 columns

\n", - "
" - ], - "text/plain": [ - " inter_no end_unix dura_A1 dura_A2 dura_A3 dura_A4 dura_A5 \\\n", - "0 201 1704406820 30 36 18 58 18 \n", - "1 177 1704406830 40 25 71 34 0 \n", - "2 210 1704406850 43 39 65 23 0 \n", - "3 175 1704406870 40 42 55 33 0 \n", - "4 176 1704406910 37 93 40 0 0 \n", - ".. ... ... ... ... ... ... ... \n", - "146 175 1704410269 40 42 55 33 0 \n", - "147 176 1704410310 37 93 40 0 0 \n", - "148 178 1704410310 38 39 42 41 0 \n", - "149 202 1704410320 46 114 0 0 0 \n", - "150 201 1704410340 30 36 18 58 18 \n", - "\n", - " dura_A6 dura_A7 dura_A8 dura_B1 dura_B2 dura_B3 dura_B4 dura_B5 \\\n", - "0 0 0 0 30 36 18 58 18 \n", - "1 0 0 0 40 25 71 34 0 \n", - "2 0 0 0 24 58 65 23 0 \n", - "3 0 0 0 40 42 29 59 0 \n", - "4 0 0 0 37 93 40 0 0 \n", - ".. ... ... ... ... ... ... ... ... \n", - "146 0 0 0 40 42 29 59 0 \n", - "147 0 0 0 37 93 40 0 0 \n", - "148 0 0 0 38 39 62 21 0 \n", - "149 0 0 0 46 114 0 0 0 \n", - "150 0 0 0 30 36 18 58 18 \n", - "\n", - " dura_B6 dura_B7 dura_B8 cycle \n", - "0 0 0 0 160 \n", - "1 0 0 0 170 \n", - "2 0 0 0 170 \n", - "3 0 0 0 170 \n", - "4 0 0 0 170 \n", - ".. ... ... ... ... \n", - "146 0 0 0 170 \n", - "147 0 0 0 170 \n", - "148 0 0 0 160 \n", - "149 0 0 0 160 \n", - "150 0 0 0 160 \n", - "\n", - "[151 rows x 19 columns]" - ] - }, - "execution_count": 30, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], + "source": [ + "def matching_main():\n", + " match1 = pd.read_csv('../../Data/tables/moves/match1.csv', index_col=0)\n", + " match2 = make_match2(match1)\n", + " match3 = make_match3(match2)\n", + " match4 = make_match4(match3)\n", + " match5 = make_match5(match4)\n", + " match6 = make_match6(match5)\n", + " matching = make_matching(match6)\n", + " return matching\n", + "matching = matching_main()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# B. 5초 간격으로 이동류번호 수집" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "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" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "def save_movement():\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')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# C. 5분 간격으로 신호이력 수집 및 통합테이블 생성" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "midnight = int(datetime(2024, 1, 5, 0, 0, 0).timestamp())\n", + "next_day = int(datetime(2024, 1, 6, 0, 0, 0).timestamp())\n", + "fmins = range(midnight, next_day, 300) # fmins : unix time by Five MINuteS" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [], "source": [ - "Rhists = make_rhistory(100)\n", - "Rhists" + "def make_splits(plan):\n", + " # 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", + " return splits, isplits\n", + "\n", + "def make_timetable(plan):\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", + " return timetable\n", + "\n", + "# inter2node\n", + "inter_node = pd.read_csv('../../Data/tables/inter_node.csv', index_col=0)\n", + "inter2node = dict(zip(inter_node['inter_no'], inter_node['node_id']))" ] }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 14, "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", + "def make_rhists(present_time, timetable, plan, history):\n", + " # 1. 조회시점의 유닉스 타임 이전의 신호이력 수집\n", + " rhistory = history.copy() # recent history\n", + " rhistory = rhistory[(rhistory.end_unix < present_time)]\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'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]].sum() // 2 # 현시시간 합\n", + " # 이전 유닉스 존재하지 않음 : 현시시간 합의 차\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", + " # 이전 유닉스 존재, abs < 10 : 이전 유닉스\n", + " if abs(pre_unix - start_unix) < 10:\n", " start_unix = pre_unix\n", - " else: # abs >= 10\n", + " # 이전 유닉스 존재, abs >=10 : 현시시간 합의 차\n", + " else:\n", " pass\n", - " rhistory.loc[i, 'start_unix'] = start_unix\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[['inter_no', 'start_unix', 'cycle']][rhistory.inter_no==175]\n", " rhistory = rhistory[['inter_no', 'start_unix'] + [f'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)] + ['cycle']]\n", "\n", + " # 2-1. 참값 판단 프로세스\n", + " hours = np.array(range(midnight, next_day + 1, 3600)) # 정각에 해당하는 시각들 목록\n", + "\n", + " def calculate_DS(rhist, curr_unix):\n", + " ghour_lt_curr_unix = hours[hours <= curr_unix].max() # the greatest hour less than (or equal to) curr_unix\n", + " start_unixes = rhist.start_unix.unique()\n", + " start_unixes_lt_ghour = np.sort(start_unixes[start_unixes < ghour_lt_curr_unix]) # start unixes less than ghour_lt_curr_unix\n", + " # 기준유닉스(base_unix) : curr_unix보다 작은 hour 중에서 가장 큰 값으로부터 다섯 번째로 작은 start_unix\n", + " if list(start_unixes_lt_ghour):\n", + " base_unix = start_unixes_lt_ghour[-5]\n", + " # start_unixes_lt_ghour가 비었을 경우에는 맨 앞 start_unix로 base_unix를 지정\n", + " else:\n", + " base_unix = rhist.start_unix.min()\n", + " D_n = curr_unix - base_unix\n", + " S_n_durs = rhist[(rhist.start_unix > base_unix) & (rhist.start_unix <= curr_unix)] \\\n", + " [[f'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]]\n", + " S_n = S_n_durs.values.sum() // 2\n", + " return D_n, S_n\n", + "\n", + " rhists = []\n", + " for inter_no in sorted(rhistory.inter_no.unique()):\n", + " rhist = rhistory.copy()[rhistory.inter_no==inter_no]\n", + " rhist = rhist.drop_duplicates(subset=['start_unix']).reset_index(drop=True)\n", + "\n", + " # D_n 및 S_n 값 정의\n", + " rhist['D_n'] = 0 # D_n : 시간차이\n", + " rhist['S_n'] = 0 # S_n : 현시시간합\n", + " for n in range(len(rhist)):\n", + " curr_unix = rhist.iloc[n].start_unix # current start_unix\n", + " rhist.loc[n, ['D_n', 'S_n']] = calculate_DS(rhist, curr_unix)\n", + "\n", + " # 이전시각, 현재시각\n", + " prev_unix = rhist.loc[0, 'start_unix'] # previous start_unix\n", + " curr_unix = rhist.loc[1, 'start_unix'] # current start_unix\n", + "\n", + " # rhist의 마지막 행에 도달할 때까지 반복\n", + " while True:\n", + " n = rhist[rhist.start_unix==curr_unix].index[0]\n", + " cycle = rhist.loc[n, 'cycle']\n", + " D_n = rhist.loc[n, 'D_n']\n", + " S_n = rhist.loc[n, 'S_n']\n", + " # 참값인 경우\n", + " if (abs(D_n - S_n) <= 5):\n", + " pass\n", + " # 참값이 아닌 경우\n", + " else:\n", + " # 2-1-1. 결측치 처리 : 인접한 두 start_unix의 차이가 계획된 주기의 두 배보다 크면 결측이 일어났다고 판단, 신호계획의 현시시간으로 \"대체\"\n", + " if curr_unix - prev_unix >= 2 * cycle:\n", + " # prev_unix를 계획된 주기만큼 늘려가면서 한 행씩 채워나간다.\n", + " # (curr_unix와의 차이가 계획된 주기보다 작거나 같아질 때까지)\n", + " new_rows = []\n", + " while curr_unix - prev_unix > cycle:\n", + " prev_unix += cycle\n", + " # 신호 계획(prow) 불러오기\n", + " start_seconds = np.array(timetable.start_seconds)\n", + " idx = (start_seconds <= prev_unix).sum() - 1\n", + " start_hour = timetable.iloc[idx].start_hour\n", + " start_minute = timetable.iloc[idx].start_minute\n", + " prow = plan.copy()[(plan.inter_no==inter_no) & (plan.start_hour==start_hour) & (plan.start_minute==start_minute)] # planned row\n", + " # prow에서 필요한 부분을 rhist에 추가\n", + " prow['start_unix'] = prev_unix\n", + " prow = prow.drop(['start_hour', 'start_minute', 'offset'], axis=1)\n", + " cycle = prow.iloc[0].cycle\n", + " rhist = pd.concat([rhist, prow])\n", + " rhist = rhist.sort_values(by='start_unix').reset_index(drop=True)\n", + " n += 1\n", + "\n", + " # 2-1-2. 이상치 처리 : 비율에 따라 해당 행을 \"삭제\"(R_n <= 0.5) 또는 \"조정\"(R_n > 0.5)한다\n", + " R_n = (curr_unix - prev_unix) / cycle # R_n : 비율\n", + " # R_n이 0.5보다 작거나 같으면 해당 행을 삭제\n", + " if R_n <= 0.5:\n", + " rhist = rhist.drop(index=n).reset_index(drop=True)\n", + " # 행삭제에 따른 curr_unix, R_n 재정의\n", + " curr_unix = rhist.loc[n, 'start_unix']\n", + " R_n = (curr_unix - prev_unix) / cycle # R_n : 비율\n", + "\n", + " # R_n이 0.5보다 크면 해당 행 조정 (비율을 유지한 채로 현시시간 대체)\n", + " if R_n > 0.5:\n", + " # 신호 계획(prow) 불러오기\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 = plan[(plan.inter_no==inter_no) & (plan.start_hour==start_hour) & (plan.start_minute==start_minute)] # planned row\n", + " # 조정된 현시시간 (prow에 R_n을 곱하고 정수로 바꿈)\n", + " adjusted_dur = prow.copy()[[f'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]] * R_n\n", + " int_parts = adjusted_dur.iloc[0].apply(lambda x: int(x))\n", + " frac_parts = adjusted_dur.iloc[0] - int_parts\n", + " difference = round(adjusted_dur.iloc[0].sum()) - int_parts.sum()\n", + " for _ in range(difference): # 소수 부분이 가장 큰 상위 '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에 조정된 현시시간을 반영\n", + " rhist.loc[n, [f'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]] = int_parts.values\n", + " rhist.loc[n, 'cycle'] = int_parts.sum().sum() // 2\n", + "\n", + " if n == rhist.index[-1]:\n", + " break\n", + " prev_unix = curr_unix\n", + " curr_unix = rhist.loc[n+1, 'start_unix']\n", + "\n", + " # 생략해도 무방할 코드\n", + " rhist = rhist.reset_index(drop=True)\n", + " rhist = rhist.sort_values(by=['start_unix'])\n", + "\n", + " # D_n 및 S_n 값 재정의\n", + " for n in range(len(rhist)):\n", + " curr_unix = rhist.iloc[n].start_unix # current start_unix\n", + " rhist.loc[n, ['D_n', 'S_n']] = calculate_DS(rhist, curr_unix)\n", + " rhists.append(rhist)\n", + " rhists = pd.concat(rhists).sort_values(by=['start_unix','inter_no'])\n", + " rhists = rhists[rhists.start_unix >= present_time - 3600]\n", + " rhists = rhists.drop(columns=['D_n', 'S_n'])\n", + " return rhists" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "def make_hrhists(rhists, isplits, timetable):\n", " # 계층화된 형태로 변환\n", - " hrhistory = [] # hierarchied recent history\n", - " for i, row in rhistory.iterrows():\n", + " hrhists = [] # hierarchied recent history\n", + " for i, row in rhists.iterrows():\n", " inter_no = row.inter_no\n", " start_unix = row.start_unix\n", "\n", @@ -8023,15 +796,66 @@ " durations.append(abs(durs_A[ja-1] - durs_B[ja-1]))\n", " new_rows = pd.DataFrame({'inter_no':[inter_no] * len(durations), 'start_unix':[start_unix] * len(durations),\n", " 'phas_A':phas_As, 'phas_B':phas_Bs, 'duration':durations})\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", + " hrhists.append(new_rows)\n", + " hrhists = pd.concat(hrhists)\n", + " hrhists = hrhists.sort_values(by = ['start_unix', 'inter_no', 'phas_A', 'phas_B']).reset_index(drop=True)\n", + " return hrhists" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "def make_movements():\n", + " movements_path = '../../Data/tables/movements/'\n", + " movements_list = [pd.read_csv(movements_path + file, index_col=0) for file in tqdm(os.listdir(movements_path))]\n", + " movements = pd.concat(movements_list)\n", + " movements = movements.drop(columns=['start_unix'])\n", + " movements = movements.drop_duplicates()\n", + " movements = movements.sort_values(by=['inter_no', 'phas_A', 'phas_B'])\n", + " movements = movements.reset_index(drop=True)\n", + " movements.to_csv(movements_path + 'movements.csv')\n", + " return movements" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "def update_movement(hrhists, movement, movements):\n", + " # 중복을 제거하고 (inter_no, start_unix) 쌍을 만듭니다.\n", + " hrhists_inter_unix = set(hrhists[['inter_no', 'start_unix']].drop_duplicates().itertuples(index=False, name=None))\n", + " movement_inter_unix = set(movement[['inter_no', 'start_unix']].drop_duplicates().itertuples(index=False, name=None))\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']) # 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", + " # hrhists에는 있지만 movement에는 없는 (inter_no, start_unix) 쌍을 찾습니다.\n", + " missing_in_movement = hrhists_inter_unix - movement_inter_unix\n", "\n", + " # 새로운 행들을 생성합니다.\n", + " new_rows = []\n", + " for inter_no, start_unix in missing_in_movement:\n", + " # movements에서 해당 inter_no의 데이터를 찾습니다.\n", + " new_row = movements[movements['inter_no'] == inter_no].copy()\n", + " # start_unix 값을 설정합니다.\n", + " new_row['start_unix'] = start_unix\n", + " new_rows.append(new_row)\n", + "\n", + " # 새로운 데이터프레임을 생성하고 기존 movement 데이터프레임과 합칩니다.\n", + " new_movement = pd.concat(new_rows, ignore_index=True)\n", + " movement_updated = pd.concat([movement, new_movement], ignore_index=True)\n", + " return movement_updated" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "def make_histid(present_time, movedur):\n", " # 이동류 매칭 테이블에서 진입id, 진출id를 가져와서 붙임.\n", " for i, row in movedur.iterrows():\n", " inter_no = row.inter_no\n", @@ -8064,168 +888,328 @@ " histid['node_id'] = histid['inter_no'].map(inter2node)\n", " histid = histid[['inter_no', 'node_id', 'start_unix', 'phas_A', 'phas_B', 'duration', 'inc_edge_A', 'out_edge_A', 'inc_edge_B', 'out_edge_B']]\n", " histid = histid[histid.start_unix > present_time - 3600]\n", - " # 시뮬레이션 시작시각 : 현재시각 - 600\n", - " # 시뮬레이션 종료시각 : 현재시각 - 300\n", - " # 현재시각 : present_time, PT\n", - " # PT-900 ... PT-600 ... PT-300 ... PT\n", " return histid" ] }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "m = 120\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'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]].sum() // 2 # 현시시간 합\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'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)] + ['cycle']]\n", - "\n", - "# rhistoryy = rhistory.copy()[rhistory.inter_no==175]\n", - "# rhistoryy['diff'] = rhistoryy['start_unix'].diff()\n", - "\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", - "\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", - " phas_As = [isplit[j][0] for j in isplit.keys()]\n", - " phas_Bs = [isplit[j][1] for j in isplit.keys()]\n", - " durs_A = row[[f'dura_A{j}' for j in range(1,9)]]\n", - " durs_B = row[[f'dura_B{j}' for j in range(1,9)]]\n", - " durations = []\n", - " for j in range(1, len(isplit)+1):\n", - " ja = isplit[j][0]\n", - " jb = isplit[j][1]\n", - " if ja == jb:\n", - " durations.append(min(durs_A[ja-1], durs_B[jb-1]))\n", - " else:\n", - " durations.append(abs(durs_A[ja-1] - durs_B[ja-1]))\n", - " new_rows = pd.DataFrame({'inter_no':[inter_no] * len(durations), 'start_unix':[start_unix] * len(durations),\n", - " 'phas_A':phas_As, 'phas_B':phas_Bs, 'duration':durations})\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", - "hrhistoryy = rhistory.copy()[rhistory.inter_no==175]\n", - "hrhistoryy['diff'] = hrhistoryy['start_unix'].diff()\n", - "\n", - "# display(hrhistoryy[:60])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "for inter_no in sorted(plan.inter_no.unique()):\n", - " print(inter_no)\n", - " movement = time2movement[present_time]\n", - " movementt = movement.copy()[movement.inter_no==inter_no]\n", - " hrhistoryy = rhistory.copy()[rhistory.inter_no==inter_no]\n", - " mdts = sorted(movementt.start_unix.unique())\n", - " hdts = sorted(hrhistoryy.start_unix.unique())\n", - " import matplotlib.pyplot as plt\n", - " plt.scatter(mdts, [0]*len(mdts), c='b')\n", - " plt.scatter(hdts, [1]*len(hdts), c='r')\n", - " plt.show()\n", - " # display(movementt)\n", - " # display(hrhistoryy)" - ] - }, - { - "cell_type": "code", - "execution_count": null, + "execution_count": 44, "metadata": {}, "outputs": [], "source": [ - "# 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']) # 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", - "\n", - "# 이동류 매칭 테이블에서 진입id, 진출id를 가져와서 붙임.\n", - "for i, row in movedur.iterrows():\n", - " inter_no = row.inter_no\n", - " start_unix = row.start_unix\n", - " # incoming and outgoing edges A\n", - " move_A = row.move_A\n", - " if move_A in [17, 18]:\n", - " inc_edge_A = np.nan\n", - " out_edge_A = np.nan\n", - " else:\n", - " match_A = matching[(matching.inter_no == inter_no) & (matching.move_no == move_A)].iloc[0]\n", - " inc_edge_A = match_A.inc_edge\n", - " out_edge_A = match_A.out_edge\n", - " movedur.loc[i, ['inc_edge_A', 'out_edge_A']] = [inc_edge_A, out_edge_A]\n", - " # incoming and outgoing edges B\n", - " move_B = row.move_B\n", - " if move_B in [17, 18]:\n", - " inc_edge_B = np.nan\n", - " out_edge_B = np.nan\n", - " else:\n", - " match_B = matching[(matching.inter_no == inter_no) & (matching.move_no == move_B)].iloc[0]\n", - " inc_edge_B = match_B.inc_edge\n", - " out_edge_B = match_B.out_edge\n", - " movedur.loc[i, ['inc_edge_B', 'out_edge_B']] = [inc_edge_B, out_edge_B]\n", - "\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", - "histid['node_id'] = histid['inter_no'].map(inter2node)\n", - "histid = histid[['inter_no', 'node_id', 'start_unix', 'phas_A', 'phas_B', 'duration', 'inc_edge_A', 'out_edge_A', 'inc_edge_B', 'out_edge_B']]\n", - "histid = histid[histid.start_unix > present_time - 3600]\n", - "# 시뮬레이션 시작시각 : 현재시각 - 600\n", - "# 시뮬레이션 종료시각 : 현재시각 - 300\n", - "# 현재시각 : present_time, PT\n", - "# PT-900 ... PT-600 ... PT-300 ... PT\n", - "\n", - "histidd = histid.copy()[histid.inter_no==175]\n", - "histidd['diff'] = histidd['start_unix'].diff()\n", - "histidd[:60]" + "def histid_main(m):\n", + " '''\n", + " 통합테이블(histid)를 만드는 함수\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", + "\n", + " output : histid (통합테이블, HISTory with edge_IDs)\n", + " - 컬럼 : inter_no, node_id, start_unix, phas_A, phas_B, duration, inc_edge_A, out_edge_A, inc_edge_B, out_edge_B\n", + "\n", + " 주요 데이터, 중간산출물 및 결과물 :\n", + " # 데이터\n", + " - history : 신호이력 (inter_no, end_unix, dura_Aj, dura_Bj, cycle, offset)\n", + " - plan : 신호계획 (inter_no, start_hour, start_minute, dura_Aj, dura_Bj cycle, offset)\n", + " # 중간산출물\n", + " - rhists (recent history)\n", + " - history에서 현재 시각 이전의 데이터를 가져옴.\n", + " - end_unix를 start_unix로 변환\n", + " - 참값판단 프로세스(결측·이상치 처리)\n", + " - 컬럼 : inter_no, start_unix, dura_Aj, dura_Bj, cycle\n", + " - hrhists (hierarchized recent history)\n", + " - rhists를 계층화\n", + " - 컬럼 : inter_no, start_unix, phas_A, phas_B, duration\n", + " - movements\n", + " - 각 교차로에 대하여 현시별로 이동류를 정해놓음.\n", + " - join시 사용하기 위함.\n", + " - 한 번 만들어놓고 두고두고 사용함.\n", + " - 컬럼 : inter_no, phas_A, phas_B, move_A, move_B\n", + " - movement\n", + " - 현재 시점에서의 이동류정보\n", + " - 컬럼 : inter_no, phas_A, phas_B, move_A, move_B, start_unix\n", + " - movement_updated\n", + " - movement와 hrhists를 join하기 전에, movement에는 없지만 hrhists에는 있는 start_unix에 대한 이동류 정보를 가져와 movement에 붙임\n", + " - 이동류정보는 앞서 정의한 movements에서 가져옴.\n", + " - 컬럼 : inter_no, phas_A, phas_B, move_A, move_B, start_unix\n", + " - movedur\n", + " - hrhists와 movement_updated를 join\n", + " - 컬럼 : inter_no, phas_A, phas_B, move_A, move_B, start_unix, duration\n", + " # 결과\n", + "\n", + " '''\n", + " midnight = int(datetime(2024, 1, 5, 0, 0, 0).timestamp())\n", + " next_day = int(datetime(2024, 1, 6, 0, 0, 0).timestamp())\n", + " fmins = range(midnight, next_day, 300) # fmins : unix time by Five MINuteS\n", + "\n", + " # 사용할 표준 테이블 목록\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", + "\n", + " # 참고할 딕셔너리, 데이터프레임 등 목록\n", + " splits, isplits = make_splits(plan)\n", + " timetable = make_timetable(plan)\n", + "\n", + " # 현재시점\n", + " present_time = fmins[m]\n", + " print(datetime.fromtimestamp(present_time))\n", + "\n", + " # rhists, hrhists\n", + " rhists = make_rhists(present_time, timetable, plan, history)\n", + " hrhists = make_hrhists(rhists, isplits, timetable)\n", + "\n", + " # movements, movement, movement_updated\n", + " movements = pd.read_csv('../../data/tables/movements/movements.csv', index_col=0)\n", + " movement = pd.read_csv(f'../../Data/tables/movements/movements_{present_time}.csv', index_col=0)\n", + " movement_updated = update_movement(hrhists, movement, movements)\n", + "\n", + " # movedur\n", + " movedur = pd.merge(movement_updated, hrhists, how='inner', on=['inter_no', 'start_unix', 'phas_A', 'phas_B']) # 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", + "\n", + " # histid\n", + " histid = make_histid(present_time, movedur)\n", + "\n", + " \n", + " # hrhists['start_dt'] = hrhists['start_unix'].map(lambda x:datetime.fromtimestamp(x))\n", + "\n", + " return histid" ] }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 45, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "2024-01-05 08:20:00\n" + "2024-01-05 02:30:00\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \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_nonode_idstart_unixphas_Aphas_Bdurationinc_edge_Aout_edge_Ainc_edge_Bout_edge_B
0175u0017043858401137-571542797_02571500487_01-571500487_01571542797_02
1175u0017043858402239-571500487_01571545870_01-571542797_02571510153_01
2175u0017043858403325571545870_02571510153_01571545870_02571542797_02
3175u0017043858403430571545870_02571510153_01571510153_02571545870_01
4175u0017043858404429571510153_02571500487_01571510153_02571545870_01
.................................
764201i817043892203317571500617_02571500618_01571500618_02571500617_01
765201i817043892204458571500617_02571500618_01571500617_02571500569_01
766201i817043892205517571500583_01571500617_01571500583_01571500569_01
767202i917043892201139571510152_02-571510152_01571510152_01571510152_01.65
768202i9170438922022101NaNNaNNaNNaN
\n", + "

769 rows × 10 columns

\n", + "
" + ], + "text/plain": [ + " inter_no node_id start_unix phas_A phas_B duration inc_edge_A \\\n", + "0 175 u00 1704385840 1 1 37 -571542797_02 \n", + "1 175 u00 1704385840 2 2 39 -571500487_01 \n", + "2 175 u00 1704385840 3 3 25 571545870_02 \n", + "3 175 u00 1704385840 3 4 30 571545870_02 \n", + "4 175 u00 1704385840 4 4 29 571510153_02 \n", + ".. ... ... ... ... ... ... ... \n", + "764 201 i8 1704389220 3 3 17 571500617_02 \n", + "765 201 i8 1704389220 4 4 58 571500617_02 \n", + "766 201 i8 1704389220 5 5 17 571500583_01 \n", + "767 202 i9 1704389220 1 1 39 571510152_02 \n", + "768 202 i9 1704389220 2 2 101 NaN \n", + "\n", + " out_edge_A inc_edge_B out_edge_B \n", + "0 571500487_01 -571500487_01 571542797_02 \n", + "1 571545870_01 -571542797_02 571510153_01 \n", + "2 571510153_01 571545870_02 571542797_02 \n", + "3 571510153_01 571510153_02 571545870_01 \n", + "4 571500487_01 571510153_02 571545870_01 \n", + ".. ... ... ... \n", + "764 571500618_01 571500618_02 571500617_01 \n", + "765 571500618_01 571500617_02 571500569_01 \n", + "766 571500617_01 571500583_01 571500569_01 \n", + "767 -571510152_01 571510152_01 571510152_01.65 \n", + "768 NaN NaN NaN \n", + "\n", + "[769 rows x 10 columns]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2024-01-05 02:35:00\n" ] }, { @@ -8264,508 +1248,190 @@ " \n", " \n", " 0\n", - " 177\n", - " i2\n", - " 1704406830\n", + " 201\n", + " i8\n", + " 1704386139\n", " 1\n", " 1\n", - " 40\n", - " -571542809_01\n", - " 571542811_01\n", - " 571542811_02\n", - " 571542809_01\n", + " 24\n", + " -571500569_01\n", + " 571500583_02\n", + " -571500569_01\n", + " 571500618_01\n", " \n", " \n", " 1\n", - " 177\n", - " i2\n", - " 1704406830\n", + " 201\n", + " i8\n", + " 1704386139\n", " 2\n", " 2\n", - " 25\n", - " 571542811_02\n", - " 571542107_01\n", - " -571542809_01\n", - " 571542809_01\n", + " 24\n", + " 571500618_02\n", + " 571500583_02\n", + " 571500618_02\n", + " 571500617_01\n", " \n", " \n", " 2\n", - " 177\n", - " i2\n", - " 1704406830\n", + " 201\n", + " i8\n", + " 1704386139\n", " 3\n", " 3\n", - " 71\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", + " 17\n", + " 571500617_02\n", + " 571500618_01\n", + " 571500618_02\n", + " 571500617_01\n", " \n", " \n", " 3\n", - " 177\n", - " i2\n", - " 1704406830\n", + " 201\n", + " i8\n", + " 1704386139\n", " 4\n", " 4\n", - " 34\n", - " -571542809_01\n", - " 571542811_01\n", - " 571542107_02\n", - " 571542809_01\n", + " 58\n", + " 571500617_02\n", + " 571500618_01\n", + " 571500617_02\n", + " 571500569_01\n", " \n", " \n", " 4\n", - " 175\n", - " i0\n", - " 1704406870\n", - " 1\n", - " 1\n", - " 40\n", - " -571542797_02\n", - " 571500487_01\n", - " -571500487_01\n", - " 571542797_02\n", - " \n", - " \n", - " 5\n", - " 175\n", - " i0\n", - " 1704406870\n", - " 2\n", - " 2\n", - " 42\n", - " -571500487_01\n", - " 571545870_01\n", - " -571542797_02\n", - " 571510153_01\n", - " \n", - " \n", - " 6\n", - " 175\n", - " i0\n", - " 1704406870\n", - " 3\n", - " 3\n", - " 29\n", - " 571545870_02\n", - " 571510153_01\n", - " 571545870_02\n", - " 571542797_02\n", + " 201\n", + " i8\n", + " 1704386139\n", + " 5\n", + " 5\n", + " 17\n", + " 571500583_01\n", + " 571500617_01\n", + " 571500583_01\n", + " 571500569_01\n", " \n", " \n", - " 7\n", - " 175\n", - " i0\n", - " 1704406870\n", - " 3\n", - " 4\n", - " 26\n", - " 571545870_02\n", - " 571510153_01\n", - " 571510153_02\n", - " 571545870_01\n", + " ...\n", + " ...\n", + " ...\n", + " ...\n", + " ...\n", + " ...\n", + " ...\n", + " ...\n", + " ...\n", + " ...\n", + " ...\n", " \n", " \n", - " 8\n", + " 768\n", " 175\n", - " i0\n", - " 1704406870\n", + " u00\n", + " 1704389520\n", " 4\n", " 4\n", - " 33\n", + " 29\n", " 571510153_02\n", " 571500487_01\n", " 571510153_02\n", " 571545870_01\n", " \n", " \n", - " 9\n", - " 176\n", - " i1\n", - " 1704406910\n", - " 1\n", - " 1\n", - " 37\n", - " -571542810_01\n", - " -571542797_02.99\n", - " 571542797_02.99\n", - " 571542810_01\n", - " \n", - " \n", - " 10\n", - " 176\n", - " i1\n", - " 1704406910\n", - " 2\n", - " 2\n", - " 93\n", - " -571542810_01\n", - " -571542797_02.99\n", - " -571542810_01\n", - " 571543469_01\n", - " \n", - " \n", - " 11\n", - " 176\n", - " i1\n", - " 1704406910\n", - " 3\n", - " 3\n", - " 40\n", - " 571543469_02\n", - " -571542797_02.99\n", - " NaN\n", - " NaN\n", - " \n", - " \n", - " 12\n", - " 178\n", - " i3\n", - " 1704406950\n", - " 1\n", - " 1\n", - " 38\n", - " 571540304_02\n", - " 571556450_01\n", - " 571556450_02\n", - " 571540304_01\n", - " \n", - " \n", - " 13\n", - " 178\n", - " i3\n", - " 1704406950\n", - " 2\n", - " 2\n", - " 39\n", - " 571556450_02\n", - " 571500475_01\n", - " 571540304_02\n", - " 571540303_01\n", - " \n", - " \n", - " 14\n", - " 178\n", - " i3\n", - " 1704406950\n", - " 3\n", - " 3\n", - " 42\n", - " 571540303_02.21\n", - " 571556450_01\n", - " 571540303_02.21\n", - " 571500475_01\n", - " \n", - " \n", - " 15\n", - " 178\n", - " i3\n", - " 1704406950\n", - " 4\n", - " 4\n", - " 21\n", - " -571500475_01\n", - " 571540303_01\n", - " -571500475_01\n", - " 571540304_01\n", - " \n", - " \n", - " 16\n", - " 202\n", - " i9\n", - " 1704406950\n", - " 1\n", - " 1\n", - " 46\n", - " 571510152_02\n", - " -571510152_01\n", - " 571510152_01\n", - " 571510152_01.65\n", - " \n", - " \n", - " 17\n", - " 202\n", - " i9\n", - " 1704406950\n", - " 2\n", - " 2\n", - " 114\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " \n", - " \n", - " 18\n", - " 177\n", - " i2\n", - " 1704407000\n", + " 769\n", + " 206\n", + " i7\n", + " 1704389520\n", " 1\n", " 1\n", - " 40\n", - " -571542809_01\n", - " 571542811_01\n", - " 571542811_02\n", - " 571542809_01\n", + " 33\n", + " -571511538_02\n", + " 571542073_02\n", + " 571542073_01\n", + " 571511538_02\n", " \n", " \n", - " 19\n", - " 177\n", - " i2\n", - " 1704407000\n", + " 770\n", + " 206\n", + " i7\n", + " 1704389520\n", " 2\n", " 2\n", - " 25\n", - " 571542811_02\n", - " 571542107_01\n", - " -571542809_01\n", - " 571542809_01\n", - " \n", - " \n", - " 20\n", - " 177\n", - " i2\n", - " 1704407000\n", - " 3\n", - " 3\n", - " 71\n", + " 35\n", " NaN\n", " NaN\n", " NaN\n", " NaN\n", " \n", " \n", - " 21\n", - " 177\n", - " i2\n", - " 1704407000\n", - " 4\n", - " 4\n", - " 34\n", - " -571542809_01\n", - " 571542811_01\n", - " 571542107_02\n", - " 571542809_01\n", - " \n", - " \n", - " 22\n", - " 175\n", - " i0\n", - " 1704407040\n", - " 1\n", - " 1\n", - " 40\n", - " -571542797_02\n", - " 571500487_01\n", - " -571500487_01\n", - " 571542797_02\n", - " \n", - " \n", - " 23\n", - " 175\n", - " i0\n", - " 1704407040\n", - " 2\n", - " 2\n", - " 42\n", - " -571500487_01\n", - " 571545870_01\n", - " -571542797_02\n", - " 571510153_01\n", - " \n", - " \n", - " 24\n", - " 175\n", - " i0\n", - " 1704407040\n", - " 3\n", + " 771\n", + " 206\n", + " i7\n", + " 1704389520\n", " 3\n", - " 29\n", - " 571545870_02\n", - " 571510153_01\n", - " 571545870_02\n", - " 571542797_02\n", - " \n", - " \n", - " 25\n", - " 175\n", - " i0\n", - " 1704407040\n", " 3\n", - " 4\n", " 26\n", - " 571545870_02\n", - " 571510153_01\n", - " 571510153_02\n", - " 571545870_01\n", + " -571511538_02\n", + " 571542073_02\n", + " 571542073_01\n", + " 571511538_02\n", " \n", " \n", - " 26\n", - " 175\n", - " i0\n", - " 1704407040\n", + " 772\n", + " 206\n", + " i7\n", + " 1704389520\n", " 4\n", " 4\n", - " 33\n", - " 571510153_02\n", - " 571500487_01\n", - " 571510153_02\n", - " 571545870_01\n", - " \n", - " \n", - " 27\n", - " 176\n", - " i1\n", - " 1704407080\n", - " 1\n", - " 1\n", - " 37\n", - " -571542810_01\n", - " -571542797_02.99\n", - " 571542797_02.99\n", - " 571542810_01\n", - " \n", - " \n", - " 28\n", - " 176\n", - " i1\n", - " 1704407080\n", - " 2\n", - " 2\n", - " 93\n", - " -571542810_01\n", - " -571542797_02.99\n", - " -571542810_01\n", - " 571543469_01\n", - " \n", - " \n", - " 29\n", - " 176\n", - " i1\n", - " 1704407080\n", - " 3\n", - " 3\n", - " 40\n", - " 571543469_02\n", - " -571542797_02.99\n", + " 26\n", + " NaN\n", + " NaN\n", " NaN\n", " NaN\n", " \n", " \n", "\n", + "

773 rows × 10 columns

\n", "" ], "text/plain": [ - " inter_no node_id start_unix phas_A phas_B duration inc_edge_A \\\n", - "0 177 i2 1704406830 1 1 40 -571542809_01 \n", - "1 177 i2 1704406830 2 2 25 571542811_02 \n", - "2 177 i2 1704406830 3 3 71 NaN \n", - "3 177 i2 1704406830 4 4 34 -571542809_01 \n", - "4 175 i0 1704406870 1 1 40 -571542797_02 \n", - "5 175 i0 1704406870 2 2 42 -571500487_01 \n", - "6 175 i0 1704406870 3 3 29 571545870_02 \n", - "7 175 i0 1704406870 3 4 26 571545870_02 \n", - "8 175 i0 1704406870 4 4 33 571510153_02 \n", - "9 176 i1 1704406910 1 1 37 -571542810_01 \n", - "10 176 i1 1704406910 2 2 93 -571542810_01 \n", - "11 176 i1 1704406910 3 3 40 571543469_02 \n", - "12 178 i3 1704406950 1 1 38 571540304_02 \n", - "13 178 i3 1704406950 2 2 39 571556450_02 \n", - "14 178 i3 1704406950 3 3 42 571540303_02.21 \n", - "15 178 i3 1704406950 4 4 21 -571500475_01 \n", - "16 202 i9 1704406950 1 1 46 571510152_02 \n", - "17 202 i9 1704406950 2 2 114 NaN \n", - "18 177 i2 1704407000 1 1 40 -571542809_01 \n", - "19 177 i2 1704407000 2 2 25 571542811_02 \n", - "20 177 i2 1704407000 3 3 71 NaN \n", - "21 177 i2 1704407000 4 4 34 -571542809_01 \n", - "22 175 i0 1704407040 1 1 40 -571542797_02 \n", - "23 175 i0 1704407040 2 2 42 -571500487_01 \n", - "24 175 i0 1704407040 3 3 29 571545870_02 \n", - "25 175 i0 1704407040 3 4 26 571545870_02 \n", - "26 175 i0 1704407040 4 4 33 571510153_02 \n", - "27 176 i1 1704407080 1 1 37 -571542810_01 \n", - "28 176 i1 1704407080 2 2 93 -571542810_01 \n", - "29 176 i1 1704407080 3 3 40 571543469_02 \n", - "\n", - " out_edge_A inc_edge_B out_edge_B \n", - "0 571542811_01 571542811_02 571542809_01 \n", - "1 571542107_01 -571542809_01 571542809_01 \n", - "2 NaN NaN NaN \n", - "3 571542811_01 571542107_02 571542809_01 \n", - "4 571500487_01 -571500487_01 571542797_02 \n", - "5 571545870_01 -571542797_02 571510153_01 \n", - "6 571510153_01 571545870_02 571542797_02 \n", - "7 571510153_01 571510153_02 571545870_01 \n", - "8 571500487_01 571510153_02 571545870_01 \n", - "9 -571542797_02.99 571542797_02.99 571542810_01 \n", - "10 -571542797_02.99 -571542810_01 571543469_01 \n", - "11 -571542797_02.99 NaN NaN \n", - "12 571556450_01 571556450_02 571540304_01 \n", - "13 571500475_01 571540304_02 571540303_01 \n", - "14 571556450_01 571540303_02.21 571500475_01 \n", - "15 571540303_01 -571500475_01 571540304_01 \n", - "16 -571510152_01 571510152_01 571510152_01.65 \n", - "17 NaN NaN NaN \n", - "18 571542811_01 571542811_02 571542809_01 \n", - "19 571542107_01 -571542809_01 571542809_01 \n", - "20 NaN NaN NaN \n", - "21 571542811_01 571542107_02 571542809_01 \n", - "22 571500487_01 -571500487_01 571542797_02 \n", - "23 571545870_01 -571542797_02 571510153_01 \n", - "24 571510153_01 571545870_02 571542797_02 \n", - "25 571510153_01 571510153_02 571545870_01 \n", - "26 571500487_01 571510153_02 571545870_01 \n", - "27 -571542797_02.99 571542797_02.99 571542810_01 \n", - "28 -571542797_02.99 -571542810_01 571543469_01 \n", - "29 -571542797_02.99 NaN NaN " + " inter_no node_id start_unix phas_A phas_B duration inc_edge_A \\\n", + "0 201 i8 1704386139 1 1 24 -571500569_01 \n", + "1 201 i8 1704386139 2 2 24 571500618_02 \n", + "2 201 i8 1704386139 3 3 17 571500617_02 \n", + "3 201 i8 1704386139 4 4 58 571500617_02 \n", + "4 201 i8 1704386139 5 5 17 571500583_01 \n", + ".. ... ... ... ... ... ... ... \n", + "768 175 u00 1704389520 4 4 29 571510153_02 \n", + "769 206 i7 1704389520 1 1 33 -571511538_02 \n", + "770 206 i7 1704389520 2 2 35 NaN \n", + "771 206 i7 1704389520 3 3 26 -571511538_02 \n", + "772 206 i7 1704389520 4 4 26 NaN \n", + "\n", + " out_edge_A inc_edge_B out_edge_B \n", + "0 571500583_02 -571500569_01 571500618_01 \n", + "1 571500583_02 571500618_02 571500617_01 \n", + "2 571500618_01 571500618_02 571500617_01 \n", + "3 571500618_01 571500617_02 571500569_01 \n", + "4 571500617_01 571500583_01 571500569_01 \n", + ".. ... ... ... \n", + "768 571500487_01 571510153_02 571545870_01 \n", + "769 571542073_02 571542073_01 571511538_02 \n", + "770 NaN NaN NaN \n", + "771 571542073_02 571542073_01 571511538_02 \n", + "772 NaN NaN NaN \n", + "\n", + "[773 rows x 10 columns]" ] }, - "execution_count": 18, "metadata": {}, - "output_type": "execute_result" + "output_type": "display_data" } ], "source": [ - "make_histid(100)[:30]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "inter_no = 175\n", - "rhist = make_histid(100)\n", - "rhis = rhist.copy()[rhist.inter_no==inter_no]\n", - "rhis['diff'] = rhis['start_unix'].diff()\n", - "rhis[:60]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "inter_no = 175\n", - "histid = make_histid(100)\n", - "his = histid.copy()[histid.inter_no==inter_no]\n", - "his['diff'] = his['start_unix'].diff()\n", - "his[:60]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "for m in range(30, 288):\n", - " print(m)\n", - " make_histid(m).to_csv(f'../../Data/tables/histids/histids_{fmins[m]}.csv')" + "for m in range(30, 32):\n", + " histid = histid_main(m)\n", + " display(histid)" ] } ], diff --git a/Data/tables/histids/histids_1704389400.csv b/Data/tables/histids/histids_1704389400.csv index 149c0e6b2..d8f6f5577 100644 --- a/Data/tables/histids/histids_1704389400.csv +++ b/Data/tables/histids/histids_1704389400.csv @@ -1,145 +1,195 @@ -,inter_no,node_id,start_unix,phas_A,phas_B,duration,inc_edge_A,out_edge_A,inc_edge_B,out_edge_B -467,178,i3,1704388520,1,1,38,571540304_02,571556450_01,571556450_02,571540304_01 -468,178,i3,1704388520,2,2,39,571556450_02,571500475_01,571540304_02,571540303_01 -469,178,i3,1704388520,3,3,40,571540303_02.21,571556450_01,571540303_02.21,571500475_01 -470,178,i3,1704388520,4,4,23,-571500475_01,571540303_01,-571500475_01,571540304_01 -471,201,i8,1704388520,1,1,24,-571500569_01,571500583_02,-571500569_01,571500618_01 -472,201,i8,1704388520,2,2,24,571500618_02,571500583_02,571500618_02,571500617_01 -473,201,i8,1704388520,3,3,17,571500617_02,571500618_01,571500618_02,571500617_01 -474,201,i8,1704388520,4,4,58,571500617_02,571500618_01,571500617_02,571500569_01 -475,201,i8,1704388520,5,5,17,571500583_01,571500617_01,571500583_01,571500569_01 -476,176,i1,1704388550,1,1,37,-571542810_01,-571542797_02.99,571542797_02.99,571542810_01 -477,176,i1,1704388550,2,2,73,-571542810_01,-571542797_02.99,-571542810_01,571543469_01 -478,176,i1,1704388550,3,3,40,571543469_02,-571542797_02.99,, -479,175,i0,1704388560,1,1,37,-571542797_02,571500487_01,-571500487_01,571542797_02 -480,175,i0,1704388560,2,2,39,-571500487_01,571545870_01,-571542797_02,571510153_01 -481,175,i0,1704388560,3,3,25,571545870_02,571510153_01,571545870_02,571542797_02 -482,175,i0,1704388560,3,4,30,571545870_02,571510153_01,571510153_02,571545870_01 -483,175,i0,1704388560,4,4,29,571510153_02,571500487_01,571510153_02,571545870_01 -484,206,i7,1704388560,1,1,33,-571511538_02,571542073_02,571542073_01,571511538_02 -485,206,i7,1704388560,2,2,35,,,, -486,206,i7,1704388560,3,3,26,-571511538_02,571542073_02,571542073_01,571511538_02 -487,206,i7,1704388560,4,4,26,,,, -488,210,i6,1704388560,1,1,24,-571542115_01,571500535_01,, -489,210,i6,1704388560,1,2,19,-571542115_01,571500535_01,571500535_02.18,571542115_01 -490,210,i6,1704388560,2,2,29,571500535_02.18,571511538_01,571500535_02.18,571542115_01 -491,210,i6,1704388560,3,3,56,571511538_02.121,571542115_01,571511538_02.121,571500585_01 -492,210,i6,1704388560,4,4,22,571500585_02,571511538_01,571500585_02,571500535_01 -493,178,i3,1704388660,1,1,38,571540304_02,571556450_01,571556450_02,571540304_01 -494,178,i3,1704388660,2,2,39,571556450_02,571500475_01,571540304_02,571540303_01 -495,178,i3,1704388660,3,3,40,571540303_02.21,571556450_01,571540303_02.21,571500475_01 -496,178,i3,1704388660,4,4,23,-571500475_01,571540303_01,-571500475_01,571540304_01 -497,201,i8,1704388660,1,1,24,-571500569_01,571500583_02,-571500569_01,571500618_01 -498,201,i8,1704388660,2,2,24,571500618_02,571500583_02,571500618_02,571500617_01 -499,201,i8,1704388660,3,3,17,571500617_02,571500618_01,571500618_02,571500617_01 -500,201,i8,1704388660,4,4,58,571500617_02,571500618_01,571500617_02,571500569_01 -501,201,i8,1704388660,5,5,17,571500583_01,571500617_01,571500583_01,571500569_01 -502,202,i9,1704388660,1,1,39,571510152_02,-571510152_01,571510152_01,571510152_01.65 -503,202,i9,1704388660,2,2,101,,,, -504,206,i7,1704388680,1,1,33,-571511538_02,571542073_02,571542073_01,571511538_02 -505,206,i7,1704388680,2,2,35,,,, -506,206,i7,1704388680,3,3,26,-571511538_02,571542073_02,571542073_01,571511538_02 -507,206,i7,1704388680,4,4,26,,,, -508,176,i1,1704388700,1,1,37,-571542810_01,-571542797_02.99,571542797_02.99,571542810_01 -509,176,i1,1704388700,2,2,73,-571542810_01,-571542797_02.99,-571542810_01,571543469_01 -510,176,i1,1704388700,3,3,40,571543469_02,-571542797_02.99,, -511,210,i6,1704388710,1,1,24,-571542115_01,571500535_01,, -512,210,i6,1704388710,1,2,19,-571542115_01,571500535_01,571500535_02.18,571542115_01 -513,210,i6,1704388710,2,2,29,571500535_02.18,571511538_01,571500535_02.18,571542115_01 -514,210,i6,1704388710,3,3,56,571511538_02.121,571542115_01,571511538_02.121,571500585_01 -515,210,i6,1704388710,4,4,22,571500585_02,571511538_01,571500585_02,571500535_01 -516,175,i0,1704388720,1,1,37,-571542797_02,571500487_01,-571500487_01,571542797_02 -517,175,i0,1704388720,2,2,39,-571500487_01,571545870_01,-571542797_02,571510153_01 -518,175,i0,1704388720,3,3,25,571545870_02,571510153_01,571545870_02,571542797_02 -519,175,i0,1704388720,3,4,30,571545870_02,571510153_01,571510153_02,571545870_01 -520,175,i0,1704388720,4,4,29,571510153_02,571500487_01,571510153_02,571545870_01 -521,178,i3,1704388800,1,1,38,571540304_02,571556450_01,571556450_02,571540304_01 -522,178,i3,1704388800,2,2,39,571556450_02,571500475_01,571540304_02,571540303_01 -523,178,i3,1704388800,3,3,40,571540303_02.21,571556450_01,571540303_02.21,571500475_01 -524,178,i3,1704388800,4,4,23,-571500475_01,571540303_01,-571500475_01,571540304_01 -525,201,i8,1704388800,1,1,24,-571500569_01,571500583_02,-571500569_01,571500618_01 -526,201,i8,1704388800,2,2,24,571500618_02,571500583_02,571500618_02,571500617_01 -527,201,i8,1704388800,3,3,17,571500617_02,571500618_01,571500618_02,571500617_01 -528,201,i8,1704388800,4,4,58,571500617_02,571500618_01,571500617_02,571500569_01 -529,201,i8,1704388800,5,5,17,571500583_01,571500617_01,571500583_01,571500569_01 -530,206,i7,1704388800,1,1,33,-571511538_02,571542073_02,571542073_01,571511538_02 -531,206,i7,1704388800,2,2,35,,,, -532,206,i7,1704388800,3,3,26,-571511538_02,571542073_02,571542073_01,571511538_02 -533,206,i7,1704388800,4,4,26,,,, -534,176,i1,1704388850,1,1,37,-571542810_01,-571542797_02.99,571542797_02.99,571542810_01 -535,176,i1,1704388850,2,2,73,-571542810_01,-571542797_02.99,-571542810_01,571543469_01 -536,176,i1,1704388850,3,3,40,571543469_02,-571542797_02.99,, -537,210,i6,1704388860,1,1,24,-571542115_01,571500535_01,, -538,210,i6,1704388860,1,2,19,-571542115_01,571500535_01,571500535_02.18,571542115_01 -539,210,i6,1704388860,2,2,29,571500535_02.18,571511538_01,571500535_02.18,571542115_01 -540,210,i6,1704388860,3,3,56,571511538_02.121,571542115_01,571511538_02.121,571500585_01 -541,210,i6,1704388860,4,4,22,571500585_02,571511538_01,571500585_02,571500535_01 -542,175,i0,1704388880,1,1,37,-571542797_02,571500487_01,-571500487_01,571542797_02 -543,175,i0,1704388880,2,2,39,-571500487_01,571545870_01,-571542797_02,571510153_01 -544,175,i0,1704388880,3,3,25,571545870_02,571510153_01,571545870_02,571542797_02 -545,175,i0,1704388880,3,4,30,571545870_02,571510153_01,571510153_02,571545870_01 -546,175,i0,1704388880,4,4,29,571510153_02,571500487_01,571510153_02,571545870_01 -547,206,i7,1704388920,1,1,33,-571511538_02,571542073_02,571542073_01,571511538_02 -548,206,i7,1704388920,2,2,35,,,, -549,206,i7,1704388920,3,3,26,-571511538_02,571542073_02,571542073_01,571511538_02 -550,206,i7,1704388920,4,4,26,,,, -551,201,i8,1704388940,1,1,24,-571500569_01,571500583_02,-571500569_01,571500618_01 -552,201,i8,1704388940,2,2,24,571500618_02,571500583_02,571500618_02,571500617_01 -553,201,i8,1704388940,3,3,17,571500617_02,571500618_01,571500618_02,571500617_01 -554,201,i8,1704388940,4,4,58,571500617_02,571500618_01,571500617_02,571500569_01 -555,201,i8,1704388940,5,5,17,571500583_01,571500617_01,571500583_01,571500569_01 -556,177,i2,1704388950,1,1,36,-571542809_01,571542811_01,571542811_02,571542809_01 -557,177,i2,1704388950,2,2,20,571542811_02,571542107_01,-571542809_01,571542809_01 -558,177,i2,1704388950,3,3,68,,,, -559,177,i2,1704388950,4,4,26,-571542809_01,571542811_01,571542107_02,571542809_01 -560,176,i1,1704389000,1,1,37,-571542810_01,-571542797_02.99,571542797_02.99,571542810_01 -561,176,i1,1704389000,2,2,73,-571542810_01,-571542797_02.99,-571542810_01,571543469_01 -562,176,i1,1704389000,3,3,40,571543469_02,-571542797_02.99,, -563,210,i6,1704389010,1,1,24,-571542115_01,571500535_01,, -564,210,i6,1704389010,1,2,19,-571542115_01,571500535_01,571500535_02.18,571542115_01 -565,210,i6,1704389010,2,2,29,571500535_02.18,571511538_01,571500535_02.18,571542115_01 -566,210,i6,1704389010,3,3,56,571511538_02.121,571542115_01,571511538_02.121,571500585_01 -567,210,i6,1704389010,4,4,22,571500585_02,571511538_01,571500585_02,571500535_01 -568,175,i0,1704389040,1,1,37,-571542797_02,571500487_01,-571500487_01,571542797_02 -569,175,i0,1704389040,2,2,39,-571500487_01,571545870_01,-571542797_02,571510153_01 -570,175,i0,1704389040,3,3,25,571545870_02,571510153_01,571545870_02,571542797_02 -571,175,i0,1704389040,3,4,30,571545870_02,571510153_01,571510153_02,571545870_01 -572,175,i0,1704389040,4,4,29,571510153_02,571500487_01,571510153_02,571545870_01 -573,206,i7,1704389040,1,1,33,-571511538_02,571542073_02,571542073_01,571511538_02 -574,206,i7,1704389040,2,2,35,,,, -575,206,i7,1704389040,3,3,26,-571511538_02,571542073_02,571542073_01,571511538_02 -576,206,i7,1704389040,4,4,26,,,, -577,201,i8,1704389080,1,1,24,-571500569_01,571500583_02,-571500569_01,571500618_01 -578,201,i8,1704389080,2,2,24,571500618_02,571500583_02,571500618_02,571500617_01 -579,201,i8,1704389080,3,3,17,571500617_02,571500618_01,571500618_02,571500617_01 -580,201,i8,1704389080,4,4,58,571500617_02,571500618_01,571500617_02,571500569_01 -581,201,i8,1704389080,5,5,17,571500583_01,571500617_01,571500583_01,571500569_01 -582,202,i9,1704389080,1,1,39,571510152_02,-571510152_01,571510152_01,571510152_01.65 -583,202,i9,1704389080,2,2,101,,,, -584,177,i2,1704389100,1,1,36,-571542809_01,571542811_01,571542811_02,571542809_01 -585,177,i2,1704389100,2,2,20,571542811_02,571542107_01,-571542809_01,571542809_01 -586,177,i2,1704389100,3,3,68,,,, -587,177,i2,1704389100,4,4,26,-571542809_01,571542811_01,571542107_02,571542809_01 -588,176,i1,1704389150,1,1,37,-571542810_01,-571542797_02.99,571542797_02.99,571542810_01 -589,176,i1,1704389150,2,2,73,-571542810_01,-571542797_02.99,-571542810_01,571543469_01 -590,176,i1,1704389150,3,3,40,571543469_02,-571542797_02.99,, -591,206,i7,1704389160,1,1,33,-571511538_02,571542073_02,571542073_01,571511538_02 -592,206,i7,1704389160,2,2,35,,,, -593,206,i7,1704389160,3,3,26,-571511538_02,571542073_02,571542073_01,571511538_02 -594,206,i7,1704389160,4,4,26,,,, -595,210,i6,1704389160,1,1,24,-571542115_01,571500535_01,, -596,210,i6,1704389160,1,2,19,-571542115_01,571500535_01,571500535_02.18,571542115_01 -597,210,i6,1704389160,2,2,29,571500535_02.18,571511538_01,571500535_02.18,571542115_01 -598,210,i6,1704389160,3,3,56,571511538_02.121,571542115_01,571511538_02.121,571500585_01 -599,210,i6,1704389160,4,4,22,571500585_02,571511538_01,571500585_02,571500535_01 -600,175,i0,1704389200,1,1,37,-571542797_02,571500487_01,-571500487_01,571542797_02 -601,175,i0,1704389200,2,2,39,-571500487_01,571545870_01,-571542797_02,571510153_01 -602,175,i0,1704389200,3,3,25,571545870_02,571510153_01,571545870_02,571542797_02 -603,175,i0,1704389200,3,4,30,571545870_02,571510153_01,571510153_02,571545870_01 -604,175,i0,1704389200,4,4,29,571510153_02,571500487_01,571510153_02,571545870_01 -605,178,i3,1704389220,1,1,38,571540304_02,571556450_01,571556450_02,571540304_01 -606,178,i3,1704389220,2,2,39,571556450_02,571500475_01,571540304_02,571540303_01 -607,178,i3,1704389220,3,3,40,571540303_02.21,571556450_01,571540303_02.21,571500475_01 -608,178,i3,1704389220,4,4,23,-571500475_01,571540303_01,-571500475_01,571540304_01 -609,202,i9,1704389220,1,1,39,571510152_02,-571510152_01,571510152_01,571510152_01.65 -610,202,i9,1704389220,2,2,101,,,, +,inter_no,start_unix,dura_A1,dura_A2,dura_A3,dura_A4,dura_A5,dura_A6,dura_A7,dura_A8,dura_B1,dura_B2,dura_B3,dura_B4,dura_B5,dura_B6,dura_B7,dura_B8,cycle +60,178,1704388800,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +60,201,1704388800,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +60,202,1704388800,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 +70,206,1704388800,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +56,177,1704388801,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +56,176,1704388850,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +56,210,1704388860,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +53,175,1704388880,37,39,55,29,0,0,0,0,37,39,25,59,0,0,0,0,160 +71,206,1704388920,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +61,202,1704388939,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 +61,178,1704388940,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +61,201,1704388940,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +57,177,1704388950,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +57,176,1704389000,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +57,210,1704389010,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +54,175,1704389040,37,39,55,29,0,0,0,0,37,39,25,59,0,0,0,0,160 +72,206,1704389040,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +62,201,1704389080,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +62,202,1704389080,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 +62,178,1704389081,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +58,177,1704389100,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +58,176,1704389150,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +73,206,1704389160,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +58,210,1704389160,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +55,175,1704389200,37,39,55,29,0,0,0,0,37,39,25,59,0,0,0,0,160 +63,178,1704389220,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +63,201,1704389220,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +63,202,1704389220,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 +59,177,1704389250,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +74,206,1704389280,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +59,176,1704389300,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +59,210,1704389310,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +64,201,1704389359,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +56,175,1704389360,37,39,55,29,0,0,0,0,37,39,25,59,0,0,0,0,160 +64,178,1704389360,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +64,202,1704389360,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 +60,177,1704389400,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +75,206,1704389400,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +60,176,1704389450,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +60,210,1704389460,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +65,178,1704389500,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +65,201,1704389500,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +65,202,1704389500,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 +57,175,1704389520,37,39,55,29,0,0,0,0,37,39,25,59,0,0,0,0,160 +76,206,1704389520,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +61,177,1704389551,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +61,176,1704389599,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +61,210,1704389610,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +66,178,1704389640,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +66,201,1704389640,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +66,202,1704389640,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 +77,206,1704389640,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +58,175,1704389680,37,39,55,29,0,0,0,0,37,39,25,59,0,0,0,0,160 +62,177,1704389700,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +62,176,1704389750,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +62,210,1704389759,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +78,206,1704389760,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +67,201,1704389779,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +67,178,1704389780,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +67,202,1704389780,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 +59,175,1704389839,37,39,55,29,0,0,0,0,37,39,25,59,0,0,0,0,160 +63,177,1704389850,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +79,206,1704389880,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +63,176,1704389900,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +63,210,1704389910,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +68,178,1704389920,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +68,201,1704389920,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +68,202,1704389920,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 +60,175,1704390000,37,39,55,29,0,0,0,0,37,39,25,59,0,0,0,0,160 +64,177,1704390000,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +80,206,1704390000,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +64,176,1704390050,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +69,178,1704390060,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +69,201,1704390060,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +69,202,1704390060,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 +64,210,1704390060,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +81,206,1704390120,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +65,177,1704390150,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +61,175,1704390160,37,39,55,29,0,0,0,0,37,39,25,59,0,0,0,0,160 +65,176,1704390200,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +70,201,1704390200,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +70,202,1704390200,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 +70,178,1704390201,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +65,210,1704390210,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +82,206,1704390240,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +66,177,1704390300,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +62,175,1704390320,37,39,55,29,0,0,0,0,37,39,25,59,0,0,0,0,160 +71,178,1704390340,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +71,201,1704390340,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +71,202,1704390340,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 +66,176,1704390349,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +83,206,1704390359,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +66,210,1704390360,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +67,177,1704390450,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +63,175,1704390480,37,39,55,29,0,0,0,0,37,39,25,59,0,0,0,0,160 +72,178,1704390480,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +72,201,1704390480,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +84,206,1704390480,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +67,176,1704390500,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +67,210,1704390510,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +72,202,1704390529,53,136,0,0,0,0,0,0,53,136,0,0,0,0,0,0,189 +68,177,1704390599,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +85,206,1704390600,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +73,178,1704390620,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +73,201,1704390620,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +64,175,1704390640,37,39,55,29,0,0,0,0,37,39,25,59,0,0,0,0,160 +68,176,1704390650,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +68,210,1704390660,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +73,202,1704390670,39,102,0,0,0,0,0,0,39,102,0,0,0,0,0,0,141 +86,206,1704390720,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +69,177,1704390750,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +74,201,1704390760,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +74,178,1704390761,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +65,175,1704390800,37,39,55,29,0,0,0,0,37,39,25,59,0,0,0,0,160 +69,176,1704390800,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +69,210,1704390809,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +74,202,1704390810,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 +87,206,1704390840,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +70,177,1704390900,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +75,178,1704390900,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +75,201,1704390900,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +70,176,1704390950,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +75,202,1704390950,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 +66,175,1704390960,37,39,55,29,0,0,0,0,37,39,25,59,0,0,0,0,160 +88,206,1704390960,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +70,210,1704390960,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +76,201,1704391040,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +76,178,1704391041,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +71,177,1704391050,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +89,206,1704391080,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +76,202,1704391090,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 +71,176,1704391100,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +71,210,1704391110,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +67,175,1704391119,37,39,55,29,0,0,0,0,37,39,25,59,0,0,0,0,160 +77,178,1704391180,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +77,201,1704391180,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +90,206,1704391200,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +72,177,1704391201,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +77,202,1704391230,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 +72,176,1704391250,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +72,210,1704391260,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +68,175,1704391280,37,39,55,29,0,0,0,0,37,39,25,59,0,0,0,0,160 +78,178,1704391320,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +78,201,1704391320,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +91,206,1704391320,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +73,177,1704391350,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +78,202,1704391370,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 +73,176,1704391399,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +73,210,1704391410,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +69,175,1704391440,37,39,55,29,0,0,0,0,37,39,25,59,0,0,0,0,160 +92,206,1704391440,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +79,201,1704391460,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +79,178,1704391461,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +74,177,1704391500,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +79,202,1704391509,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 +74,176,1704391550,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +93,206,1704391560,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +74,210,1704391560,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +70,175,1704391600,37,39,55,29,0,0,0,0,37,39,25,59,0,0,0,0,160 +80,178,1704391600,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +80,201,1704391600,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +75,177,1704391650,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +80,202,1704391650,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 +94,206,1704391680,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +75,176,1704391700,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +75,210,1704391710,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +81,201,1704391740,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +81,178,1704391741,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +71,175,1704391760,37,39,55,29,0,0,0,0,37,39,25,59,0,0,0,0,160 +81,202,1704391790,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 +76,177,1704391800,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +95,206,1704391801,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +76,176,1704391850,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +76,210,1704391859,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +82,178,1704391880,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +82,201,1704391880,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +72,175,1704391920,37,39,55,29,0,0,0,0,37,39,25,59,0,0,0,0,160 +96,206,1704391920,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +82,202,1704391930,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 +77,177,1704391950,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +77,176,1704392000,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +77,210,1704392010,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +83,178,1704392020,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +83,201,1704392020,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +97,206,1704392040,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +83,202,1704392070,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 +73,175,1704392080,37,39,55,29,0,0,0,0,37,39,25,59,0,0,0,0,160 +78,177,1704392100,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +78,176,1704392151,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +78,210,1704392159,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +84,178,1704392160,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +84,201,1704392160,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +98,206,1704392160,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +84,202,1704392211,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 diff --git a/Data/tables/histids/histids_1704389700.csv b/Data/tables/histids/histids_1704389700.csv index e9025ecb4..d8f6f5577 100644 --- a/Data/tables/histids/histids_1704389700.csv +++ b/Data/tables/histids/histids_1704389700.csv @@ -1,134 +1,195 @@ -,inter_no,node_id,start_unix,phas_A,phas_B,duration,inc_edge_A,out_edge_A,inc_edge_B,out_edge_B -489,176,i1,1704388850,1,1,37,-571542810_01,-571542797_02.99,571542797_02.99,571542810_01 -490,176,i1,1704388850,2,2,73,-571542810_01,-571542797_02.99,-571542810_01,571543469_01 -491,176,i1,1704388850,3,3,40,571543469_02,-571542797_02.99,, -492,210,i6,1704388860,1,1,24,-571542115_01,571500535_01,, -493,210,i6,1704388860,1,2,19,-571542115_01,571500535_01,571500535_02.18,571542115_01 -494,210,i6,1704388860,2,2,29,571500535_02.18,571511538_01,571500535_02.18,571542115_01 -495,210,i6,1704388860,3,3,56,571511538_02.121,571542115_01,571511538_02.121,571500585_01 -496,210,i6,1704388860,4,4,22,571500585_02,571511538_01,571500585_02,571500535_01 -497,175,i0,1704388880,1,1,37,-571542797_02,571500487_01,-571500487_01,571542797_02 -498,175,i0,1704388880,2,2,39,-571500487_01,571545870_01,-571542797_02,571510153_01 -499,175,i0,1704388880,3,3,25,571545870_02,571510153_01,571545870_02,571542797_02 -500,175,i0,1704388880,3,4,30,571545870_02,571510153_01,571510153_02,571545870_01 -501,175,i0,1704388880,4,4,29,571510153_02,571500487_01,571510153_02,571545870_01 -502,206,i7,1704388920,1,1,33,-571511538_02,571542073_02,571542073_01,571511538_02 -503,206,i7,1704388920,2,2,35,,,, -504,206,i7,1704388920,3,3,26,-571511538_02,571542073_02,571542073_01,571511538_02 -505,206,i7,1704388920,4,4,26,,,, -506,201,i8,1704388940,1,1,24,-571500569_01,571500583_02,-571500569_01,571500618_01 -507,201,i8,1704388940,2,2,24,571500618_02,571500583_02,571500618_02,571500617_01 -508,201,i8,1704388940,3,3,17,571500617_02,571500618_01,571500618_02,571500617_01 -509,201,i8,1704388940,4,4,58,571500617_02,571500618_01,571500617_02,571500569_01 -510,201,i8,1704388940,5,5,17,571500583_01,571500617_01,571500583_01,571500569_01 -511,177,i2,1704388950,1,1,36,-571542809_01,571542811_01,571542811_02,571542809_01 -512,177,i2,1704388950,2,2,20,571542811_02,571542107_01,-571542809_01,571542809_01 -513,177,i2,1704388950,3,3,68,,,, -514,177,i2,1704388950,4,4,26,-571542809_01,571542811_01,571542107_02,571542809_01 -515,176,i1,1704389000,1,1,37,-571542810_01,-571542797_02.99,571542797_02.99,571542810_01 -516,176,i1,1704389000,2,2,73,-571542810_01,-571542797_02.99,-571542810_01,571543469_01 -517,176,i1,1704389000,3,3,40,571543469_02,-571542797_02.99,, -518,210,i6,1704389010,1,1,24,-571542115_01,571500535_01,, -519,210,i6,1704389010,1,2,19,-571542115_01,571500535_01,571500535_02.18,571542115_01 -520,210,i6,1704389010,2,2,29,571500535_02.18,571511538_01,571500535_02.18,571542115_01 -521,210,i6,1704389010,3,3,56,571511538_02.121,571542115_01,571511538_02.121,571500585_01 -522,210,i6,1704389010,4,4,22,571500585_02,571511538_01,571500585_02,571500535_01 -523,175,i0,1704389040,1,1,37,-571542797_02,571500487_01,-571500487_01,571542797_02 -524,175,i0,1704389040,2,2,39,-571500487_01,571545870_01,-571542797_02,571510153_01 -525,175,i0,1704389040,3,3,25,571545870_02,571510153_01,571545870_02,571542797_02 -526,175,i0,1704389040,3,4,30,571545870_02,571510153_01,571510153_02,571545870_01 -527,175,i0,1704389040,4,4,29,571510153_02,571500487_01,571510153_02,571545870_01 -528,206,i7,1704389040,1,1,33,-571511538_02,571542073_02,571542073_01,571511538_02 -529,206,i7,1704389040,2,2,35,,,, -530,206,i7,1704389040,3,3,26,-571511538_02,571542073_02,571542073_01,571511538_02 -531,206,i7,1704389040,4,4,26,,,, -532,201,i8,1704389080,1,1,24,-571500569_01,571500583_02,-571500569_01,571500618_01 -533,201,i8,1704389080,2,2,24,571500618_02,571500583_02,571500618_02,571500617_01 -534,201,i8,1704389080,3,3,17,571500617_02,571500618_01,571500618_02,571500617_01 -535,201,i8,1704389080,4,4,58,571500617_02,571500618_01,571500617_02,571500569_01 -536,201,i8,1704389080,5,5,17,571500583_01,571500617_01,571500583_01,571500569_01 -537,202,i9,1704389080,1,1,39,571510152_02,-571510152_01,571510152_01,571510152_01.65 -538,202,i9,1704389080,2,2,101,,,, -539,177,i2,1704389100,1,1,36,-571542809_01,571542811_01,571542811_02,571542809_01 -540,177,i2,1704389100,2,2,20,571542811_02,571542107_01,-571542809_01,571542809_01 -541,177,i2,1704389100,3,3,68,,,, -542,177,i2,1704389100,4,4,26,-571542809_01,571542811_01,571542107_02,571542809_01 -543,176,i1,1704389150,1,1,37,-571542810_01,-571542797_02.99,571542797_02.99,571542810_01 -544,176,i1,1704389150,2,2,73,-571542810_01,-571542797_02.99,-571542810_01,571543469_01 -545,176,i1,1704389150,3,3,40,571543469_02,-571542797_02.99,, -546,206,i7,1704389160,1,1,33,-571511538_02,571542073_02,571542073_01,571511538_02 -547,206,i7,1704389160,2,2,35,,,, -548,206,i7,1704389160,3,3,26,-571511538_02,571542073_02,571542073_01,571511538_02 -549,206,i7,1704389160,4,4,26,,,, -550,210,i6,1704389160,1,1,24,-571542115_01,571500535_01,, -551,210,i6,1704389160,1,2,19,-571542115_01,571500535_01,571500535_02.18,571542115_01 -552,210,i6,1704389160,2,2,29,571500535_02.18,571511538_01,571500535_02.18,571542115_01 -553,210,i6,1704389160,3,3,56,571511538_02.121,571542115_01,571511538_02.121,571500585_01 -554,210,i6,1704389160,4,4,22,571500585_02,571511538_01,571500585_02,571500535_01 -555,175,i0,1704389200,1,1,37,-571542797_02,571500487_01,-571500487_01,571542797_02 -556,175,i0,1704389200,2,2,39,-571500487_01,571545870_01,-571542797_02,571510153_01 -557,175,i0,1704389200,3,3,25,571545870_02,571510153_01,571545870_02,571542797_02 -558,175,i0,1704389200,3,4,30,571545870_02,571510153_01,571510153_02,571545870_01 -559,175,i0,1704389200,4,4,29,571510153_02,571500487_01,571510153_02,571545870_01 -560,178,i3,1704389220,1,1,38,571540304_02,571556450_01,571556450_02,571540304_01 -561,178,i3,1704389220,2,2,39,571556450_02,571500475_01,571540304_02,571540303_01 -562,178,i3,1704389220,3,3,40,571540303_02.21,571556450_01,571540303_02.21,571500475_01 -563,178,i3,1704389220,4,4,23,-571500475_01,571540303_01,-571500475_01,571540304_01 -564,202,i9,1704389220,1,1,39,571510152_02,-571510152_01,571510152_01,571510152_01.65 -565,202,i9,1704389220,2,2,101,,,, -566,177,i2,1704389250,1,1,36,-571542809_01,571542811_01,571542811_02,571542809_01 -567,177,i2,1704389250,2,2,20,571542811_02,571542107_01,-571542809_01,571542809_01 -568,177,i2,1704389250,3,3,68,,,, -569,177,i2,1704389250,4,4,26,-571542809_01,571542811_01,571542107_02,571542809_01 -570,206,i7,1704389280,1,1,33,-571511538_02,571542073_02,571542073_01,571511538_02 -571,206,i7,1704389280,2,2,35,,,, -572,206,i7,1704389280,3,3,26,-571511538_02,571542073_02,571542073_01,571511538_02 -573,206,i7,1704389280,4,4,26,,,, -574,176,i1,1704389300,1,1,37,-571542810_01,-571542797_02.99,571542797_02.99,571542810_01 -575,176,i1,1704389300,2,2,73,-571542810_01,-571542797_02.99,-571542810_01,571543469_01 -576,176,i1,1704389300,3,3,40,571543469_02,-571542797_02.99,, -577,210,i6,1704389310,1,1,24,-571542115_01,571500535_01,, -578,210,i6,1704389310,1,2,19,-571542115_01,571500535_01,571500535_02.18,571542115_01 -579,210,i6,1704389310,2,2,29,571500535_02.18,571511538_01,571500535_02.18,571542115_01 -580,210,i6,1704389310,3,3,56,571511538_02.121,571542115_01,571511538_02.121,571500585_01 -581,210,i6,1704389310,4,4,22,571500585_02,571511538_01,571500585_02,571500535_01 -582,175,i0,1704389360,1,1,37,-571542797_02,571500487_01,-571500487_01,571542797_02 -583,175,i0,1704389360,2,2,39,-571500487_01,571545870_01,-571542797_02,571510153_01 -584,175,i0,1704389360,3,3,25,571545870_02,571510153_01,571545870_02,571542797_02 -585,175,i0,1704389360,3,4,30,571545870_02,571510153_01,571510153_02,571545870_01 -586,175,i0,1704389360,4,4,29,571510153_02,571500487_01,571510153_02,571545870_01 -587,178,i3,1704389360,1,1,38,571540304_02,571556450_01,571556450_02,571540304_01 -588,178,i3,1704389360,2,2,39,571556450_02,571500475_01,571540304_02,571540303_01 -589,178,i3,1704389360,3,3,40,571540303_02.21,571556450_01,571540303_02.21,571500475_01 -590,178,i3,1704389360,4,4,23,-571500475_01,571540303_01,-571500475_01,571540304_01 -591,202,i9,1704389360,1,1,39,571510152_02,-571510152_01,571510152_01,571510152_01.65 -592,202,i9,1704389360,2,2,101,,,, -593,206,i7,1704389400,1,1,33,-571511538_02,571542073_02,571542073_01,571511538_02 -594,206,i7,1704389400,2,2,35,,,, -595,206,i7,1704389400,3,3,26,-571511538_02,571542073_02,571542073_01,571511538_02 -596,206,i7,1704389400,4,4,26,,,, -597,210,i6,1704389460,1,1,24,-571542115_01,571500535_01,, -598,210,i6,1704389460,1,2,19,-571542115_01,571500535_01,571500535_02.18,571542115_01 -599,210,i6,1704389460,2,2,29,571500535_02.18,571511538_01,571500535_02.18,571542115_01 -600,210,i6,1704389460,3,3,56,571511538_02.121,571542115_01,571511538_02.121,571500585_01 -601,210,i6,1704389460,4,4,22,571500585_02,571511538_01,571500585_02,571500535_01 -602,178,i3,1704389500,1,1,38,571540304_02,571556450_01,571556450_02,571540304_01 -603,178,i3,1704389500,2,2,39,571556450_02,571500475_01,571540304_02,571540303_01 -604,178,i3,1704389500,3,3,40,571540303_02.21,571556450_01,571540303_02.21,571500475_01 -605,178,i3,1704389500,4,4,23,-571500475_01,571540303_01,-571500475_01,571540304_01 -606,201,i8,1704389500,1,1,24,-571500569_01,571500583_02,-571500569_01,571500618_01 -607,201,i8,1704389500,2,2,24,571500618_02,571500583_02,571500618_02,571500617_01 -608,201,i8,1704389500,3,3,17,571500617_02,571500618_01,571500618_02,571500617_01 -609,201,i8,1704389500,4,4,58,571500617_02,571500618_01,571500617_02,571500569_01 -610,201,i8,1704389500,5,5,17,571500583_01,571500617_01,571500583_01,571500569_01 -611,202,i9,1704389500,1,1,39,571510152_02,-571510152_01,571510152_01,571510152_01.65 -612,202,i9,1704389500,2,2,101,,,, -613,175,i0,1704389520,1,1,37,-571542797_02,571500487_01,-571500487_01,571542797_02 -614,175,i0,1704389520,2,2,39,-571500487_01,571545870_01,-571542797_02,571510153_01 -615,175,i0,1704389520,3,3,25,571545870_02,571510153_01,571545870_02,571542797_02 -616,175,i0,1704389520,3,4,30,571545870_02,571510153_01,571510153_02,571545870_01 -617,175,i0,1704389520,4,4,29,571510153_02,571500487_01,571510153_02,571545870_01 -618,206,i7,1704389520,1,1,33,-571511538_02,571542073_02,571542073_01,571511538_02 -619,206,i7,1704389520,2,2,35,,,, -620,206,i7,1704389520,3,3,26,-571511538_02,571542073_02,571542073_01,571511538_02 -621,206,i7,1704389520,4,4,26,,,, +,inter_no,start_unix,dura_A1,dura_A2,dura_A3,dura_A4,dura_A5,dura_A6,dura_A7,dura_A8,dura_B1,dura_B2,dura_B3,dura_B4,dura_B5,dura_B6,dura_B7,dura_B8,cycle +60,178,1704388800,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +60,201,1704388800,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +60,202,1704388800,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 +70,206,1704388800,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +56,177,1704388801,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +56,176,1704388850,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +56,210,1704388860,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +53,175,1704388880,37,39,55,29,0,0,0,0,37,39,25,59,0,0,0,0,160 +71,206,1704388920,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +61,202,1704388939,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 +61,178,1704388940,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +61,201,1704388940,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +57,177,1704388950,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +57,176,1704389000,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +57,210,1704389010,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +54,175,1704389040,37,39,55,29,0,0,0,0,37,39,25,59,0,0,0,0,160 +72,206,1704389040,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +62,201,1704389080,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +62,202,1704389080,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 +62,178,1704389081,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +58,177,1704389100,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +58,176,1704389150,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +73,206,1704389160,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +58,210,1704389160,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +55,175,1704389200,37,39,55,29,0,0,0,0,37,39,25,59,0,0,0,0,160 +63,178,1704389220,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +63,201,1704389220,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +63,202,1704389220,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 +59,177,1704389250,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +74,206,1704389280,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +59,176,1704389300,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +59,210,1704389310,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +64,201,1704389359,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +56,175,1704389360,37,39,55,29,0,0,0,0,37,39,25,59,0,0,0,0,160 +64,178,1704389360,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +64,202,1704389360,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 +60,177,1704389400,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +75,206,1704389400,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +60,176,1704389450,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +60,210,1704389460,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +65,178,1704389500,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +65,201,1704389500,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +65,202,1704389500,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 +57,175,1704389520,37,39,55,29,0,0,0,0,37,39,25,59,0,0,0,0,160 +76,206,1704389520,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +61,177,1704389551,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +61,176,1704389599,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +61,210,1704389610,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +66,178,1704389640,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +66,201,1704389640,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +66,202,1704389640,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 +77,206,1704389640,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +58,175,1704389680,37,39,55,29,0,0,0,0,37,39,25,59,0,0,0,0,160 +62,177,1704389700,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +62,176,1704389750,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +62,210,1704389759,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +78,206,1704389760,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +67,201,1704389779,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +67,178,1704389780,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +67,202,1704389780,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 +59,175,1704389839,37,39,55,29,0,0,0,0,37,39,25,59,0,0,0,0,160 +63,177,1704389850,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +79,206,1704389880,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +63,176,1704389900,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +63,210,1704389910,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +68,178,1704389920,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +68,201,1704389920,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +68,202,1704389920,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 +60,175,1704390000,37,39,55,29,0,0,0,0,37,39,25,59,0,0,0,0,160 +64,177,1704390000,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +80,206,1704390000,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +64,176,1704390050,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +69,178,1704390060,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +69,201,1704390060,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +69,202,1704390060,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 +64,210,1704390060,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +81,206,1704390120,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +65,177,1704390150,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +61,175,1704390160,37,39,55,29,0,0,0,0,37,39,25,59,0,0,0,0,160 +65,176,1704390200,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +70,201,1704390200,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +70,202,1704390200,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 +70,178,1704390201,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +65,210,1704390210,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +82,206,1704390240,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +66,177,1704390300,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +62,175,1704390320,37,39,55,29,0,0,0,0,37,39,25,59,0,0,0,0,160 +71,178,1704390340,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +71,201,1704390340,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +71,202,1704390340,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 +66,176,1704390349,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +83,206,1704390359,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +66,210,1704390360,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +67,177,1704390450,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +63,175,1704390480,37,39,55,29,0,0,0,0,37,39,25,59,0,0,0,0,160 +72,178,1704390480,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +72,201,1704390480,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +84,206,1704390480,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +67,176,1704390500,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +67,210,1704390510,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +72,202,1704390529,53,136,0,0,0,0,0,0,53,136,0,0,0,0,0,0,189 +68,177,1704390599,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +85,206,1704390600,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +73,178,1704390620,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +73,201,1704390620,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +64,175,1704390640,37,39,55,29,0,0,0,0,37,39,25,59,0,0,0,0,160 +68,176,1704390650,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +68,210,1704390660,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +73,202,1704390670,39,102,0,0,0,0,0,0,39,102,0,0,0,0,0,0,141 +86,206,1704390720,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +69,177,1704390750,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +74,201,1704390760,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +74,178,1704390761,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +65,175,1704390800,37,39,55,29,0,0,0,0,37,39,25,59,0,0,0,0,160 +69,176,1704390800,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +69,210,1704390809,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +74,202,1704390810,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 +87,206,1704390840,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +70,177,1704390900,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +75,178,1704390900,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +75,201,1704390900,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +70,176,1704390950,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +75,202,1704390950,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 +66,175,1704390960,37,39,55,29,0,0,0,0,37,39,25,59,0,0,0,0,160 +88,206,1704390960,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +70,210,1704390960,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +76,201,1704391040,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +76,178,1704391041,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +71,177,1704391050,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +89,206,1704391080,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +76,202,1704391090,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 +71,176,1704391100,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +71,210,1704391110,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +67,175,1704391119,37,39,55,29,0,0,0,0,37,39,25,59,0,0,0,0,160 +77,178,1704391180,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +77,201,1704391180,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +90,206,1704391200,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +72,177,1704391201,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +77,202,1704391230,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 +72,176,1704391250,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +72,210,1704391260,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +68,175,1704391280,37,39,55,29,0,0,0,0,37,39,25,59,0,0,0,0,160 +78,178,1704391320,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +78,201,1704391320,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +91,206,1704391320,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +73,177,1704391350,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +78,202,1704391370,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 +73,176,1704391399,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +73,210,1704391410,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +69,175,1704391440,37,39,55,29,0,0,0,0,37,39,25,59,0,0,0,0,160 +92,206,1704391440,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +79,201,1704391460,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +79,178,1704391461,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +74,177,1704391500,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +79,202,1704391509,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 +74,176,1704391550,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +93,206,1704391560,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +74,210,1704391560,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +70,175,1704391600,37,39,55,29,0,0,0,0,37,39,25,59,0,0,0,0,160 +80,178,1704391600,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +80,201,1704391600,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +75,177,1704391650,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +80,202,1704391650,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 +94,206,1704391680,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +75,176,1704391700,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +75,210,1704391710,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +81,201,1704391740,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +81,178,1704391741,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +71,175,1704391760,37,39,55,29,0,0,0,0,37,39,25,59,0,0,0,0,160 +81,202,1704391790,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 +76,177,1704391800,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +95,206,1704391801,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +76,176,1704391850,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +76,210,1704391859,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +82,178,1704391880,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +82,201,1704391880,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +72,175,1704391920,37,39,55,29,0,0,0,0,37,39,25,59,0,0,0,0,160 +96,206,1704391920,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +82,202,1704391930,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 +77,177,1704391950,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +77,176,1704392000,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +77,210,1704392010,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +83,178,1704392020,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +83,201,1704392020,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +97,206,1704392040,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +83,202,1704392070,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 +73,175,1704392080,37,39,55,29,0,0,0,0,37,39,25,59,0,0,0,0,160 +78,177,1704392100,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150 +78,176,1704392151,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150 +78,210,1704392159,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150 +84,178,1704392160,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140 +84,201,1704392160,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140 +98,206,1704392160,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120 +84,202,1704392211,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140 diff --git a/Data/tables/movements/movements.csv b/Data/tables/movements/movements.csv new file mode 100644 index 000000000..4d6c3e2bb --- /dev/null +++ b/Data/tables/movements/movements.csv @@ -0,0 +1,33 @@ +,inter_no,phas_A,phas_B,move_A,move_B +0,175,1,1,8,4 +1,175,2,2,7,3 +2,175,3,3,6,1 +3,175,3,4,6,2 +4,175,4,4,5,2 +5,176,1,1,8,4 +6,176,2,2,8,3 +7,176,3,3,5,18 +8,177,1,1,8,4 +9,177,2,2,7,3 +10,177,3,3,17,18 +11,177,4,4,5,1 +12,178,1,1,8,4 +13,178,2,2,7,3 +14,178,3,3,5,2 +15,178,4,4,6,1 +16,201,1,1,8,3 +17,201,2,2,5,2 +18,201,3,3,6,2 +19,201,4,4,6,1 +20,201,5,5,7,4 +21,202,1,1,6,2 +22,202,2,2,17,18 +23,206,1,1,8,4 +24,206,2,2,17,18 +25,206,3,3,8,4 +26,206,4,4,17,18 +27,210,1,1,6,18 +28,210,1,2,6,2 +29,210,2,2,5,2 +30,210,3,3,7,4 +31,210,4,4,8,3 diff --git a/Data/tables/moves/match1.csv b/Data/tables/moves/match1.csv new file mode 100644 index 000000000..4d6c3e2bb --- /dev/null +++ b/Data/tables/moves/match1.csv @@ -0,0 +1,33 @@ +,inter_no,phas_A,phas_B,move_A,move_B +0,175,1,1,8,4 +1,175,2,2,7,3 +2,175,3,3,6,1 +3,175,3,4,6,2 +4,175,4,4,5,2 +5,176,1,1,8,4 +6,176,2,2,8,3 +7,176,3,3,5,18 +8,177,1,1,8,4 +9,177,2,2,7,3 +10,177,3,3,17,18 +11,177,4,4,5,1 +12,178,1,1,8,4 +13,178,2,2,7,3 +14,178,3,3,5,2 +15,178,4,4,6,1 +16,201,1,1,8,3 +17,201,2,2,5,2 +18,201,3,3,6,2 +19,201,4,4,6,1 +20,201,5,5,7,4 +21,202,1,1,6,2 +22,202,2,2,17,18 +23,206,1,1,8,4 +24,206,2,2,17,18 +25,206,3,3,8,4 +26,206,4,4,17,18 +27,210,1,1,6,18 +28,210,1,2,6,2 +29,210,2,2,5,2 +30,210,3,3,7,4 +31,210,4,4,8,3