From 3f7a4b01c75b9a3add3785cddee58857ccd5fc0d Mon Sep 17 00:00:00 2001 From: govin08 Date: Thu, 8 Feb 2024 13:11:41 +0900 Subject: [PATCH] last modifications --- .../0207_code_reivision.ipynb | 441 ++++++++++++++ .../0207_uturn_code_change.ipynb | 548 ------------------ Documents/김선중_신호생성(240207).pptx | Bin 683525 -> 687246 bytes .../preprocess_daily.cpython-38.pyc | Bin 27676 -> 27673 bytes 4 files changed, 441 insertions(+), 548 deletions(-) create mode 100644 Analysis/0207_code_reivision/0207_code_reivision.ipynb delete mode 100644 Analysis/0207_uturn_code_change/0207_uturn_code_change.ipynb diff --git a/Analysis/0207_code_reivision/0207_code_reivision.ipynb b/Analysis/0207_code_reivision/0207_code_reivision.ipynb new file mode 100644 index 000000000..02d34e398 --- /dev/null +++ b/Analysis/0207_code_reivision/0207_code_reivision.ipynb @@ -0,0 +1,441 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "41.0\n" + ] + } + ], + "source": [ + "time_data = \"\"\"\n", + "3h\n", + "0.5h\n", + "3h\n", + "2h\n", + "2h\n", + "4h\n", + "3h\n", + "1.5h\n", + "4h\n", + "3.5h\n", + "2.5h\n", + "2h\n", + "3h\n", + "3h\n", + "2h\n", + "1h\n", + "0h\n", + "0.5h\n", + "0.5h\n", + "\"\"\"\n", + "time_list = time_data.strip().split('\\n')\n", + "total_hours = sum(float(time.replace('h', '')) for time in time_list)\n", + "print(total_hours)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1. 데이터를 로드합니다.\n", + "1-1. 네트워크가 로드되었습니다.\n", + "1-2. 테이블들이 로드되었습니다.\n", + "1-3. 네트워크의 모든 clean state requirement들을 체크했습니다.\n", + "1-4. 테이블들의 무결성 검사를 완료했습니다.\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "이동류정보 불러오는 중: 100%|██████████| 17280/17280 [00:51<00:00, 334.89it/s]\n" + ] + } + ], + "source": [ + "import sys\n", + "from datetime import datetime\n", + "sys.path.append('../../Scripts')\n", + "from preprocess_daily import DailyPreprocessor\n", + "self = DailyPreprocessor()\n", + "\n", + "# 1. 데이터 준비\n", + "self.load_data()\n", + "\n", + "self.make_match1()\n", + "self.make_match2()\n", + "self.make_match3()\n", + "self.make_match4()\n", + "self.make_match5()" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "u00 True\n", + "u20 False\n", + "u30 True\n", + "u31 True\n", + "u32 True\n", + "u60 True\n" + ] + }, + { + "ename": "NameError", + "evalue": "name 'pd' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[4], line 55\u001b[0m\n\u001b[0;32m 52\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcoord \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcoord[[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124minter_no\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mphase_no\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mring_type\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mmove_no\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124minc_dir\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mout_dir\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124minc_angle\u001b[39m\u001b[38;5;124m'\u001b[39m,\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mout_angle\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124minc_edge\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mout_edge\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mnode_id\u001b[39m\u001b[38;5;124m'\u001b[39m]]\n\u001b[0;32m 54\u001b[0m \u001b[38;5;66;03m# display(coord)\u001b[39;00m\n\u001b[1;32m---> 55\u001b[0m cmatches \u001b[38;5;241m=\u001b[39m \u001b[43mpd\u001b[49m\u001b[38;5;241m.\u001b[39mconcat(cmatches)\n\u001b[0;32m 56\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mmatch6 \u001b[38;5;241m=\u001b[39m pd\u001b[38;5;241m.\u001b[39mconcat([\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mmatch5, cmatches, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcoord])\u001b[38;5;241m.\u001b[39mdrop_duplicates()\u001b[38;5;241m.\u001b[39msort_values(by\u001b[38;5;241m=\u001b[39m[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124minter_no\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mnode_id\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mphase_no\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mring_type\u001b[39m\u001b[38;5;124m'\u001b[39m])\n\u001b[0;32m 57\u001b[0m \u001b[38;5;66;03m# self.match6.to_csv(os.path.join(self.path_intermediates, 'match6.csv'))\u001b[39;00m\n", + "\u001b[1;31mNameError\u001b[0m: name 'pd' is not defined" + ] + } + ], + "source": [ + "# self.node2inter = dict(zip(self.inter_node['node_id'], self.inter_node['inter_no']))\n", + "\n", + "# child_ids = self.inter_node[self.inter_node.inter_type=='child'].node_id.unique()\n", + "# ch2pa = {} # child to parent\n", + "# for child_id in child_ids:\n", + "# parent_no = self.inter_node[self.inter_node.node_id==child_id].inter_no.iloc[0]\n", + "# sub_inter_node = self.inter_node[self.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 self.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 = self.match5.copy()[self.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 = directions[(ind + 2) % len(directions)]\n", + "# out_dire_A = directions[(ind - 2) % len(directions)]\n", + "# out_dire_B = directions[(ind - 2) % len(directions)]\n", + "# print(child_id, ((cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_A)).any())\n", + "# # (inc_dire, out_dire_A, out_dire_B) 별로 inc_edge_id, out_edge_id를 정함\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", + "# if condition == '보행신호시':\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", + "# # 유턴신호의 이동류번호를 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", + "# self.coord['inter_no'] = self.coord['parent_id'].map(self.node2inter)\n", + "# self.coord = self.coord.rename(columns={'child_id':'node_id'})\n", + "# self.coord[['inc_dir', 'out_dir', 'inc_angle','out_angle']] = np.nan\n", + "# self.coord['move_no'] = 20\n", + "# self.coord = self.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", + "# self.match6 = pd.concat([self.match5, cmatches, self.coord]).drop_duplicates().sort_values(by=['inter_no', 'node_id', 'phase_no', 'ring_type'])\n", + "# # self.match6.to_csv(os.path.join(self.path_intermediates, 'match6.csv'))" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "ename": "AttributeError", + "evalue": "'DailyPreprocessor' object has no attribute 'match6'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mAttributeError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[5], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmatch6\u001b[49m\n", + "\u001b[1;31mAttributeError\u001b[0m: 'DailyPreprocessor' object has no attribute 'match6'" + ] + } + ], + "source": [ + "self.match6" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "splits 딕셔너리 다시 만들기" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[37 39 55 29 0 0 0 0]\n", + "[37 39 25 59 0 0 0 0]\n", + "[ 37 76 131 160 160 160 160 160]\n", + "[ 37 76 101 160 160 160 160 160]\n", + "[ 37 76 101 131 160]\n", + "[37 39 25 30 29]\n", + "{(1, 1): 37, (2, 2): 39, (3, 3): 25, (3, 4): 55, (4, 4): 29, (4, 5): 59, (5, 5): 0, (6, 6): 0, (7, 7): 0, (8, 8): 0}\n", + "\n", + "[37 39 55 29 0 0 0 0]\n", + "[37 39 25 59 0 0 0 0]\n", + "[ 0 39 55 29 0 0 0 0]\n", + "[ 0 0 55 29 0 0 0 0]\n", + "[ 0 0 30 29 0 0 0 0]\n", + "[ 0 0 30 -1 0 0 0 0]\n", + "[ 0 0 30 -1 -29 0 0 0]\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "row = self.plan.iloc[0]\n", + "# print(row)\n", + "inter_no = row.inter_no\n", + "start_hour = row.start_hour\n", + "start_minute = row.start_minute\n", + "cycle = row.cycle\n", + "\n", + "dura_A = np.array(row[[f'dura_A{j}' for j in range(1, 9)]])\n", + "dura_B = np.array(row[[f'dura_B{j}' for j in range(1, 9)]])\n", + "\n", + "print(np.array(dura_A))\n", + "print(np.array(dura_B))\n", + "\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", + "\n", + "print(np.array(cums_A))\n", + "print(np.array(cums_B))\n", + "\n", + "detailed_cums = []\n", + "combined_row = np.unique(np.concatenate((cums_A,cums_B)))\n", + "print(combined_row)\n", + "detailed_durations = np.concatenate(([combined_row[0]], np.diff(combined_row)))\n", + "\n", + "print(detailed_durations)\n", + "\n", + "desired_dict = {(1, 1): 37, (2, 2): 39, (3, 3): 25, (3, 4): 55, (4, 4): 29, (4, 5): 59, (5, 5): 0, (6, 6): 0, (7, 7): 0, (8, 8): 0}\n", + "print(desired_dict)\n", + "\n", + "print()\n", + "print(dura_A)\n", + "print(dura_B)\n", + "j = 0\n", + "for i in range(len(detailed_durations)):\n", + " dura_A[j] -= detailed_durations[i]\n", + " print(dura_A)\n", + " j += 1" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[37 39 55 29 0 0 0 0]\n", + "[37 39 25 59 0 0 0 0]\n", + "[ 37 76 131 160 160 160 160 160]\n", + "[ 37 76 101 160 160 160 160 160]\n", + "[ 37 76 101 131 160]\n", + "[37 39 25 30 29]\n", + "{(1, 1): 37, (2, 2): 39, (3, 3): 25, (3, 4): 55, (4, 4): 29, (4, 5): 59, (5, 5): 0, (6, 6): 0, (7, 7): 0, (8, 8): 0}\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "row = self.plan.iloc[0]\n", + "inter_no = row.inter_no\n", + "start_hour = row.start_hour\n", + "start_minute = row.start_minute\n", + "cycle = row.cycle\n", + "\n", + "dura_A = row[[f'dura_A{j}' for j in range(1, 9)]]\n", + "dura_B = row[[f'dura_B{j}' for j in range(1, 9)]]\n", + "\n", + "print(np.array(dura_A))\n", + "print(np.array(dura_B))\n", + "\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", + "\n", + "print(np.array(cums_A))\n", + "print(np.array(cums_B))\n", + "\n", + "detailed_cums = []\n", + "combined_row = np.unique(np.concatenate((cums_A,cums_B)))\n", + "print(combined_row)\n", + "detailed_durations = np.concatenate(([combined_row[0]], np.diff(combined_row)))\n", + "\n", + "print(detailed_durations)\n", + "\n", + "duration_dict = {}\n", + "# 두 시리즈의 길이가 같다고 가정합니다.\n", + "for i in range(len(dura_A)):\n", + " # A와 B의 현시시간이 같은 경우\n", + " if dura_A[i] == dura_B[i]:\n", + " duration_dict[(i+1, i+1)] = dura_A[i]\n", + " # A와 B의 현시시간이 다른 경우\n", + " else:\n", + " duration_dict[(i+1, i+1)] = min(dura_A[i], dura_B[i])\n", + " duration_dict[(i+1, i+2)] = max(dura_A[i], dura_B[i])\n", + "\n", + "print(duration_dict)\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", + "# print(cums_A)\n", + "# print(cums_B)\n", + "# detailed_cums = []\n", + "# combined_row = np.unique(np.concatenate((cums_A,cums_B)))\n", + "# print(combined_row)\n", + "# detailed_durations = np.concatenate(([combined_row[0]], np.diff(combined_row)))\n", + "# print(detailed_durations)" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [], + "source": [ + "# split, isplit : A,B 분리 혹은 통합시 사용될 수 있는 딕셔너리 \n", + "self.splits = {} # splits maps (inter_no, start_hour, start_minute) to split \n", + "for i, row in self.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", + " self.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", + " self.splits[(inter_no, start_hour, start_minute)][(phas_A, phas_B)] = k\n", + "self.isplits = {} # the inverse of splits\n", + "for i in self.splits:\n", + " self.isplits[i] = {self.splits[i][k]:k for k in self.splits[i]} # isplit maps k to (phas_A, phas_B)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{(175, 0, 0): {(1, 1): 1, (2, 2): 2, (3, 3): 3, (3, 4): 4, (4, 4): 5},\n", + " (175, 7, 0): {(1, 1): 1, (2, 2): 2, (3, 3): 3, (3, 4): 4, (4, 4): 5},\n", + " (175, 9, 0): {(1, 1): 1, (2, 2): 2, (3, 3): 3, (3, 4): 4, (4, 4): 5},\n", + " (175, 18, 30): {(1, 1): 1, (2, 2): 2, (3, 3): 3, (3, 4): 4, (4, 4): 5},\n", + " (176, 0, 0): {(1, 1): 1, (2, 2): 2, (3, 3): 3},\n", + " (176, 7, 0): {(1, 1): 1, (2, 2): 2, (3, 3): 3},\n", + " (176, 9, 0): {(1, 1): 1, (2, 2): 2, (3, 3): 3},\n", + " (176, 18, 30): {(1, 1): 1, (2, 2): 2, (3, 3): 3},\n", + " (177, 0, 0): {(1, 1): 1, (2, 2): 2, (3, 3): 3, (4, 4): 4},\n", + " (177, 7, 0): {(1, 1): 1, (2, 2): 2, (3, 3): 3, (4, 4): 4},\n", + " (177, 9, 0): {(1, 1): 1, (2, 2): 2, (3, 3): 3, (4, 4): 4},\n", + " (177, 18, 30): {(1, 1): 1, (2, 2): 2, (3, 3): 3, (4, 4): 4},\n", + " (178, 0, 0): {(1, 1): 1, (2, 2): 2, (3, 3): 3, (4, 4): 4},\n", + " (178, 7, 0): {(1, 1): 1, (2, 2): 2, (3, 3): 3, (4, 3): 4, (4, 4): 5},\n", + " (178, 9, 0): {(1, 1): 1, (2, 2): 2, (3, 3): 3, (4, 3): 4, (4, 4): 5},\n", + " (178, 18, 30): {(1, 1): 1, (2, 2): 2, (3, 3): 3, (4, 3): 4, (4, 4): 5},\n", + " (201, 0, 0): {(1, 1): 1, (2, 2): 2, (3, 3): 3, (4, 4): 4, (5, 5): 5},\n", + " (201, 7, 0): {(1, 1): 1, (2, 2): 2, (3, 3): 3, (4, 4): 4, (5, 5): 5},\n", + " (201, 9, 0): {(1, 1): 1, (2, 2): 2, (3, 3): 3, (4, 4): 4, (5, 5): 5},\n", + " (201, 18, 30): {(1, 1): 1, (2, 2): 2, (3, 3): 3, (4, 4): 4, (5, 5): 5},\n", + " (202, 0, 0): {(1, 1): 1, (2, 2): 2},\n", + " (202, 7, 0): {(1, 1): 1, (2, 2): 2},\n", + " (202, 9, 0): {(1, 1): 1, (2, 2): 2},\n", + " (202, 18, 30): {(1, 1): 1, (2, 2): 2},\n", + " (206, 0, 0): {(1, 1): 1, (2, 2): 2, (3, 3): 3, (4, 4): 4},\n", + " (206, 7, 0): {(1, 1): 1, (2, 2): 2, (3, 3): 3, (4, 4): 4},\n", + " (206, 9, 0): {(1, 1): 1, (2, 2): 2, (3, 3): 3, (4, 4): 4},\n", + " (206, 18, 30): {(1, 1): 1, (2, 2): 2, (3, 3): 3, (4, 4): 4},\n", + " (210, 0, 0): {(1, 1): 1, (1, 2): 2, (2, 2): 3, (3, 3): 4, (4, 4): 5},\n", + " (210, 7, 0): {(1, 1): 1, (1, 2): 2, (2, 2): 3, (3, 3): 4, (4, 4): 5},\n", + " (210, 9, 0): {(1, 1): 1, (1, 2): 2, (2, 2): 3, (3, 3): 4, (4, 4): 5},\n", + " (210, 18, 30): {(1, 1): 1, (1, 2): 2, (2, 2): 3, (3, 3): 4, (4, 4): 5}}" + ] + }, + "execution_count": 49, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "self.splits" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "rts", + "language": "python", + "name": "rts" + }, + "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/0207_uturn_code_change/0207_uturn_code_change.ipynb b/Analysis/0207_uturn_code_change/0207_uturn_code_change.ipynb deleted file mode 100644 index 615b0654d..000000000 --- a/Analysis/0207_uturn_code_change/0207_uturn_code_change.ipynb +++ /dev/null @@ -1,548 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 37, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1. 데이터를 로드합니다.\n", - "1-1. 네트워크가 로드되었습니다.\n", - "1-2. 테이블들이 로드되었습니다.\n", - "1-3. 네트워크의 모든 clean state requirement들을 체크했습니다.\n", - "1-4. 테이블들의 무결성 검사를 완료했습니다.\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "이동류정보 불러오는 중: 100%|██████████| 17280/17280 [00:13<00:00, 1247.47it/s]\n" - ] - } - ], - "source": [ - "import sys\n", - "from datetime import datetime\n", - "sys.path.append('../../Scripts')\n", - "from preprocess_daily import DailyPreprocessor\n", - "self = DailyPreprocessor()\n", - "\n", - "# 1. 데이터 준비\n", - "self.load_data()\n", - "\n", - "self.make_match1()\n", - "self.make_match2()\n", - "self.make_match3()\n", - "self.make_match4()\n", - "self.make_match5()" - ] - }, - { - "cell_type": "code", - "execution_count": 36, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "u00 True\n", - "u20 False\n", - "u30 True\n", - "u31 True\n", - "u32 True\n", - "u60 True\n" - ] - } - ], - "source": [ - "self.node2inter = dict(zip(self.inter_node['node_id'], self.inter_node['inter_no']))\n", - "\n", - "child_ids = self.inter_node[self.inter_node.inter_type=='child'].node_id.unique()\n", - "ch2pa = {} # child to parent\n", - "for child_id in child_ids:\n", - " parent_no = self.inter_node[self.inter_node.node_id==child_id].inter_no.iloc[0]\n", - " sub_inter_node = self.inter_node[self.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 self.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 = self.match5.copy()[self.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 = directions[(ind + 2) % len(directions)]\n", - " out_dire_A = directions[(ind - 2) % len(directions)]\n", - " out_dire_B = directions[(ind - 2) % len(directions)]\n", - " print(child_id, ((cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_A)).any())\n", - " # (inc_dire, out_dire_A, out_dire_B) 별로 inc_edge_id, out_edge_id를 정함\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", - " if condition == '보행신호시':\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", - " # 유턴신호의 이동류번호를 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", - "self.coord['inter_no'] = self.coord['parent_id'].map(self.node2inter)\n", - "self.coord = self.coord.rename(columns={'child_id':'node_id'})\n", - "self.coord[['inc_dir', 'out_dir', 'inc_angle','out_angle']] = np.nan\n", - "self.coord['move_no'] = 20\n", - "self.coord = self.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", - "self.match6 = pd.concat([self.match5, cmatches, self.coord]).drop_duplicates().sort_values(by=['inter_no', 'node_id', 'phase_no', 'ring_type'])\n", - "# self.match6.to_csv(os.path.join(self.path_intermediates, 'match6.csv'))" - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "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", - "
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
....................................
32102B2270090NaNNaNu60
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 2 서 동 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 NaN NaN 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]" - ] - }, - "execution_count": 34, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "self.match6" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "splits 딕셔너리 다시 만들기" - ] - }, - { - "cell_type": "code", - "execution_count": 53, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "dura_A1 37\n", - "dura_A2 39\n", - "dura_A3 55\n", - "dura_A4 29\n", - "dura_A5 0\n", - "dura_A6 0\n", - "dura_A7 0\n", - "dura_A8 0\n", - "Name: 0, dtype: int64\n", - "dura_B1 37\n", - "dura_B2 39\n", - "dura_B3 25\n", - "dura_B4 59\n", - "dura_B5 0\n", - "dura_B6 0\n", - "dura_B7 0\n", - "dura_B8 0\n", - "Name: 0, dtype: int64\n" - ] - }, - { - "ename": "NameError", - "evalue": "name 'dura_A' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[1;32mIn[53], line 11\u001b[0m\n\u001b[0;32m 9\u001b[0m duration_dict \u001b[38;5;241m=\u001b[39m {}\n\u001b[0;32m 10\u001b[0m \u001b[38;5;66;03m# 두 시리즈의 길이가 같다고 가정합니다.\u001b[39;00m\n\u001b[1;32m---> 11\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m i \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mrange\u001b[39m(\u001b[38;5;28mlen\u001b[39m(\u001b[43mdura_A\u001b[49m)):\n\u001b[0;32m 12\u001b[0m \u001b[38;5;66;03m# A와 B의 현시간이 같은 경우\u001b[39;00m\n\u001b[0;32m 13\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m dura_A[i] \u001b[38;5;241m==\u001b[39m dura_B[i]:\n\u001b[0;32m 14\u001b[0m duration_dict[(i\u001b[38;5;241m+\u001b[39m\u001b[38;5;241m1\u001b[39m, i\u001b[38;5;241m+\u001b[39m\u001b[38;5;241m1\u001b[39m)] \u001b[38;5;241m=\u001b[39m dura_A[i]\n", - "\u001b[1;31mNameError\u001b[0m: name 'dura_A' is not defined" - ] - } - ], - "source": [ - "import numpy as np\n", - "row = self.plan.iloc[0]\n", - "inter_no = row.inter_no\n", - "start_hour = row.start_hour\n", - "start_minute = row.start_minute\n", - "cycle = row.cycle\n", - "print(row[[f'dura_A{j}' for j in range(1,9)]])\n", - "print(row[[f'dura_B{j}' for j in range(1,9)]])\n", - "\n", - "\n", - "dura_A = row[[f'dura_A{j}' for j in range(1, 9)]]\n", - "dura_B = row[[f'dura_B{j}' for j in range(1, 9)]]\n", - "\n", - "duration_dict = {}\n", - "# 두 시리즈의 길이가 같다고 가정합니다.\n", - "for i in range(len(dura_A)):\n", - " # A와 B의 현시간이 같은 경우\n", - " if dura_A[i] == dura_B[i]:\n", - " duration_dict[(i+1, i+1)] = dura_A[i]\n", - " # A와 B의 현시간이 다른 경우\n", - " else:\n", - " duration_dict[(i+1, i+1)] = min(dura_A[i], dura_B[i])\n", - " duration_dict[(i+1, i+2)] = max(dura_A[i], dura_B[i])\n", - "\n", - "print(duration_dict)\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", - "# print(cums_A)\n", - "# print(cums_B)\n", - "# detailed_cums = []\n", - "# combined_row = np.unique(np.concatenate((cums_A,cums_B)))\n", - "# print(combined_row)\n", - "# detailed_durations = np.concatenate(([combined_row[0]], np.diff(combined_row)))\n", - "# print(detailed_durations)" - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "metadata": {}, - "outputs": [], - "source": [ - "# split, isplit : A,B 분리 혹은 통합시 사용될 수 있는 딕셔너리 \n", - "self.splits = {} # splits maps (inter_no, start_hour, start_minute) to split \n", - "for i, row in self.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", - " self.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", - " self.splits[(inter_no, start_hour, start_minute)][(phas_A, phas_B)] = k\n", - "self.isplits = {} # the inverse of splits\n", - "for i in self.splits:\n", - " self.isplits[i] = {self.splits[i][k]:k for k in self.splits[i]} # isplit maps k to (phas_A, phas_B)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 49, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{(175, 0, 0): {(1, 1): 1, (2, 2): 2, (3, 3): 3, (3, 4): 4, (4, 4): 5},\n", - " (175, 7, 0): {(1, 1): 1, (2, 2): 2, (3, 3): 3, (3, 4): 4, (4, 4): 5},\n", - " (175, 9, 0): {(1, 1): 1, (2, 2): 2, (3, 3): 3, (3, 4): 4, (4, 4): 5},\n", - " (175, 18, 30): {(1, 1): 1, (2, 2): 2, (3, 3): 3, (3, 4): 4, (4, 4): 5},\n", - " (176, 0, 0): {(1, 1): 1, (2, 2): 2, (3, 3): 3},\n", - " (176, 7, 0): {(1, 1): 1, (2, 2): 2, (3, 3): 3},\n", - " (176, 9, 0): {(1, 1): 1, (2, 2): 2, (3, 3): 3},\n", - " (176, 18, 30): {(1, 1): 1, (2, 2): 2, (3, 3): 3},\n", - " (177, 0, 0): {(1, 1): 1, (2, 2): 2, (3, 3): 3, (4, 4): 4},\n", - " (177, 7, 0): {(1, 1): 1, (2, 2): 2, (3, 3): 3, (4, 4): 4},\n", - " (177, 9, 0): {(1, 1): 1, (2, 2): 2, (3, 3): 3, (4, 4): 4},\n", - " (177, 18, 30): {(1, 1): 1, (2, 2): 2, (3, 3): 3, (4, 4): 4},\n", - " (178, 0, 0): {(1, 1): 1, (2, 2): 2, (3, 3): 3, (4, 4): 4},\n", - " (178, 7, 0): {(1, 1): 1, (2, 2): 2, (3, 3): 3, (4, 3): 4, (4, 4): 5},\n", - " (178, 9, 0): {(1, 1): 1, (2, 2): 2, (3, 3): 3, (4, 3): 4, (4, 4): 5},\n", - " (178, 18, 30): {(1, 1): 1, (2, 2): 2, (3, 3): 3, (4, 3): 4, (4, 4): 5},\n", - " (201, 0, 0): {(1, 1): 1, (2, 2): 2, (3, 3): 3, (4, 4): 4, (5, 5): 5},\n", - " (201, 7, 0): {(1, 1): 1, (2, 2): 2, (3, 3): 3, (4, 4): 4, (5, 5): 5},\n", - " (201, 9, 0): {(1, 1): 1, (2, 2): 2, (3, 3): 3, (4, 4): 4, (5, 5): 5},\n", - " (201, 18, 30): {(1, 1): 1, (2, 2): 2, (3, 3): 3, (4, 4): 4, (5, 5): 5},\n", - " (202, 0, 0): {(1, 1): 1, (2, 2): 2},\n", - " (202, 7, 0): {(1, 1): 1, (2, 2): 2},\n", - " (202, 9, 0): {(1, 1): 1, (2, 2): 2},\n", - " (202, 18, 30): {(1, 1): 1, (2, 2): 2},\n", - " (206, 0, 0): {(1, 1): 1, (2, 2): 2, (3, 3): 3, (4, 4): 4},\n", - " (206, 7, 0): {(1, 1): 1, (2, 2): 2, (3, 3): 3, (4, 4): 4},\n", - " (206, 9, 0): {(1, 1): 1, (2, 2): 2, (3, 3): 3, (4, 4): 4},\n", - " (206, 18, 30): {(1, 1): 1, (2, 2): 2, (3, 3): 3, (4, 4): 4},\n", - " (210, 0, 0): {(1, 1): 1, (1, 2): 2, (2, 2): 3, (3, 3): 4, (4, 4): 5},\n", - " (210, 7, 0): {(1, 1): 1, (1, 2): 2, (2, 2): 3, (3, 3): 4, (4, 4): 5},\n", - " (210, 9, 0): {(1, 1): 1, (1, 2): 2, (2, 2): 3, (3, 3): 4, (4, 4): 5},\n", - " (210, 18, 30): {(1, 1): 1, (1, 2): 2, (2, 2): 3, (3, 3): 4, (4, 4): 5}}" - ] - }, - "execution_count": 49, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "self.splits" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "rts", - "language": "python", - "name": "rts" - }, - "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/Documents/김선중_신호생성(240207).pptx b/Documents/김선중_신호생성(240207).pptx index c96317a82a7244310c17b84c0a2703d646a24e8e..4e9aaa696fa0d95c8f53214a0eea9e54326367fc 100644 GIT binary patch delta 22922 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 V(Oe7;XMsNan{l{7NA#Q-?r&Owj6?tc diff --git a/Scripts/__pycache__/preprocess_daily.cpython-38.pyc b/Scripts/__pycache__/preprocess_daily.cpython-38.pyc index 5ec61e5240f40ab60ad78b1ba089a393fd948106..6694b8dc9e1421afb92620c1faa2c784c20720a2 100644 GIT binary patch delta 1899 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