|
{
|
|
"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": "code",
|
|
"execution_count": 2,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# plan_original = pd.read_csv('../../Data/tables/plan_original.csv', index_col=0)\n",
|
|
"# plan_original_ = plan_original[plan_original.start_hour==0]\n",
|
|
"# # plan_original_ = plan_original_[plan_original_.inter_no.isin([175, 210])]\n",
|
|
"# with pd.option_context('display.max_rows', None, 'display.max_columns', None):\n",
|
|
"# display(plan_original_) # overlap : 175, 201, 210"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# 1. 이동류 매칭"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 3,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stderr",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"100%|██████████| 17280/17280 [00:13<00:00, 1309.86it/s]\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<div>\n",
|
|
"<style scoped>\n",
|
|
" .dataframe tbody tr th:only-of-type {\n",
|
|
" vertical-align: middle;\n",
|
|
" }\n",
|
|
"\n",
|
|
" .dataframe tbody tr th {\n",
|
|
" vertical-align: top;\n",
|
|
" }\n",
|
|
"\n",
|
|
" .dataframe thead th {\n",
|
|
" text-align: right;\n",
|
|
" }\n",
|
|
"</style>\n",
|
|
"<table border=\"1\" class=\"dataframe\">\n",
|
|
" <thead>\n",
|
|
" <tr style=\"text-align: right;\">\n",
|
|
" <th></th>\n",
|
|
" <th>inter_no</th>\n",
|
|
" <th>phas_A</th>\n",
|
|
" <th>phas_B</th>\n",
|
|
" <th>move_A</th>\n",
|
|
" <th>move_B</th>\n",
|
|
" </tr>\n",
|
|
" </thead>\n",
|
|
" <tbody>\n",
|
|
" <tr>\n",
|
|
" <th>0</th>\n",
|
|
" <td>175</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>8</td>\n",
|
|
" <td>4</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>1</th>\n",
|
|
" <td>175</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>7</td>\n",
|
|
" <td>3</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>2</th>\n",
|
|
" <td>175</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>6</td>\n",
|
|
" <td>1</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>3</th>\n",
|
|
" <td>175</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>4</td>\n",
|
|
" <td>6</td>\n",
|
|
" <td>2</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>4</th>\n",
|
|
" <td>175</td>\n",
|
|
" <td>4</td>\n",
|
|
" <td>4</td>\n",
|
|
" <td>5</td>\n",
|
|
" <td>2</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>5</th>\n",
|
|
" <td>176</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>8</td>\n",
|
|
" <td>4</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>6</th>\n",
|
|
" <td>176</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>8</td>\n",
|
|
" <td>3</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>7</th>\n",
|
|
" <td>176</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>5</td>\n",
|
|
" <td>18</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>8</th>\n",
|
|
" <td>177</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>8</td>\n",
|
|
" <td>4</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>9</th>\n",
|
|
" <td>177</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>7</td>\n",
|
|
" <td>3</td>\n",
|
|
" </tr>\n",
|
|
" </tbody>\n",
|
|
"</table>\n",
|
|
"</div>"
|
|
],
|
|
"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": 3,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"# [이동류번호] 불러오기\n",
|
|
"path_moves = '../../Data/tables/movements/'\n",
|
|
"csv_moves = os.listdir('../../Data/tables/movements/')\n",
|
|
"moves = [pd.read_csv(path_moves + csv_movement, index_col=0) for csv_movement 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 = match1[match1.inter_no!=212]\n",
|
|
"match1.head(10)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 4,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<div>\n",
|
|
"<style scoped>\n",
|
|
" .dataframe tbody tr th:only-of-type {\n",
|
|
" vertical-align: middle;\n",
|
|
" }\n",
|
|
"\n",
|
|
" .dataframe tbody tr th {\n",
|
|
" vertical-align: top;\n",
|
|
" }\n",
|
|
"\n",
|
|
" .dataframe thead th {\n",
|
|
" text-align: right;\n",
|
|
" }\n",
|
|
"</style>\n",
|
|
"<table border=\"1\" class=\"dataframe\">\n",
|
|
" <thead>\n",
|
|
" <tr style=\"text-align: right;\">\n",
|
|
" <th></th>\n",
|
|
" <th>inter_no</th>\n",
|
|
" <th>phase_no</th>\n",
|
|
" <th>ring_type</th>\n",
|
|
" <th>move_no</th>\n",
|
|
" </tr>\n",
|
|
" </thead>\n",
|
|
" <tbody>\n",
|
|
" <tr>\n",
|
|
" <th>0</th>\n",
|
|
" <td>175</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>8</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>0</th>\n",
|
|
" <td>175</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>4</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>1</th>\n",
|
|
" <td>175</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>7</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>1</th>\n",
|
|
" <td>175</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>3</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>2</th>\n",
|
|
" <td>175</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>6</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>2</th>\n",
|
|
" <td>175</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>1</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>4</th>\n",
|
|
" <td>175</td>\n",
|
|
" <td>4</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>5</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>3</th>\n",
|
|
" <td>175</td>\n",
|
|
" <td>4</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>2</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>5</th>\n",
|
|
" <td>176</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>8</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>5</th>\n",
|
|
" <td>176</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>4</td>\n",
|
|
" </tr>\n",
|
|
" </tbody>\n",
|
|
"</table>\n",
|
|
"</div>"
|
|
],
|
|
"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": 4,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"# 계층화\n",
|
|
"moveA = match1[['inter_no', 'phas_A', 'move_A']].copy()\n",
|
|
"moveA.columns = ['inter_no', 'phase_no', 'move_no']\n",
|
|
"moveA['ring_type'] = 'A'\n",
|
|
"moveB = match1[['inter_no', 'phas_B', 'move_B']].copy()\n",
|
|
"moveB.columns = ['inter_no', 'phase_no', 'move_no']\n",
|
|
"moveB['ring_type'] = 'B'\n",
|
|
"match2 = pd.concat([moveA, moveB]).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": 5,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<div>\n",
|
|
"<style scoped>\n",
|
|
" .dataframe tbody tr th:only-of-type {\n",
|
|
" vertical-align: middle;\n",
|
|
" }\n",
|
|
"\n",
|
|
" .dataframe tbody tr th {\n",
|
|
" vertical-align: top;\n",
|
|
" }\n",
|
|
"\n",
|
|
" .dataframe thead th {\n",
|
|
" text-align: right;\n",
|
|
" }\n",
|
|
"</style>\n",
|
|
"<table border=\"1\" class=\"dataframe\">\n",
|
|
" <thead>\n",
|
|
" <tr style=\"text-align: right;\">\n",
|
|
" <th></th>\n",
|
|
" <th>inter_no</th>\n",
|
|
" <th>phase_no</th>\n",
|
|
" <th>ring_type</th>\n",
|
|
" <th>move_no</th>\n",
|
|
" <th>inc_dir</th>\n",
|
|
" <th>out_dir</th>\n",
|
|
" </tr>\n",
|
|
" </thead>\n",
|
|
" <tbody>\n",
|
|
" <tr>\n",
|
|
" <th>0</th>\n",
|
|
" <td>175</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>8</td>\n",
|
|
" <td>남</td>\n",
|
|
" <td>북</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>1</th>\n",
|
|
" <td>175</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>4</td>\n",
|
|
" <td>북</td>\n",
|
|
" <td>남</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>2</th>\n",
|
|
" <td>175</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>7</td>\n",
|
|
" <td>북</td>\n",
|
|
" <td>동</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>3</th>\n",
|
|
" <td>175</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>남</td>\n",
|
|
" <td>서</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>4</th>\n",
|
|
" <td>175</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>6</td>\n",
|
|
" <td>동</td>\n",
|
|
" <td>서</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>...</th>\n",
|
|
" <td>...</td>\n",
|
|
" <td>...</td>\n",
|
|
" <td>...</td>\n",
|
|
" <td>...</td>\n",
|
|
" <td>...</td>\n",
|
|
" <td>...</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>59</th>\n",
|
|
" <td>210</td>\n",
|
|
" <td>4</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>남</td>\n",
|
|
" <td>서</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>60</th>\n",
|
|
" <td>211</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>6</td>\n",
|
|
" <td>동</td>\n",
|
|
" <td>서</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>61</th>\n",
|
|
" <td>211</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>동</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>62</th>\n",
|
|
" <td>211</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>17</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>63</th>\n",
|
|
" <td>211</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>18</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" </tbody>\n",
|
|
"</table>\n",
|
|
"<p>64 rows × 6 columns</p>\n",
|
|
"</div>"
|
|
],
|
|
"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",
|
|
".. ... ... ... ... ... ...\n",
|
|
"59 210 4 B 3 남 서\n",
|
|
"60 211 1 A 6 동 서\n",
|
|
"61 211 1 B 2 서 동\n",
|
|
"62 211 2 A 17 NaN NaN\n",
|
|
"63 211 2 B 18 NaN NaN\n",
|
|
"\n",
|
|
"[64 rows x 6 columns]"
|
|
]
|
|
},
|
|
"execution_count": 5,
|
|
"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', left_on='move_no', right_on='이동류번호').drop_duplicates()\n",
|
|
"match3.rename(columns={'진입방향': 'inc_dir', '진출방향': 'out_dir'}, inplace=True)\n",
|
|
"match3.drop('이동류번호', axis=1, inplace=True)\n",
|
|
"match3"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 6,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<div>\n",
|
|
"<style scoped>\n",
|
|
" .dataframe tbody tr th:only-of-type {\n",
|
|
" vertical-align: middle;\n",
|
|
" }\n",
|
|
"\n",
|
|
" .dataframe tbody tr th {\n",
|
|
" vertical-align: top;\n",
|
|
" }\n",
|
|
"\n",
|
|
" .dataframe thead th {\n",
|
|
" text-align: right;\n",
|
|
" }\n",
|
|
"</style>\n",
|
|
"<table border=\"1\" class=\"dataframe\">\n",
|
|
" <thead>\n",
|
|
" <tr style=\"text-align: right;\">\n",
|
|
" <th></th>\n",
|
|
" <th>inter_no</th>\n",
|
|
" <th>phase_no</th>\n",
|
|
" <th>ring_type</th>\n",
|
|
" <th>move_no</th>\n",
|
|
" <th>inc_dir</th>\n",
|
|
" <th>out_dir</th>\n",
|
|
" <th>inc_angle</th>\n",
|
|
" <th>out_angle</th>\n",
|
|
" </tr>\n",
|
|
" </thead>\n",
|
|
" <tbody>\n",
|
|
" <tr>\n",
|
|
" <th>0</th>\n",
|
|
" <td>175</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>8</td>\n",
|
|
" <td>남</td>\n",
|
|
" <td>북</td>\n",
|
|
" <td>179</td>\n",
|
|
" <td>004</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>1</th>\n",
|
|
" <td>175</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>4</td>\n",
|
|
" <td>북</td>\n",
|
|
" <td>남</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>2</th>\n",
|
|
" <td>175</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>7</td>\n",
|
|
" <td>북</td>\n",
|
|
" <td>동</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>3</th>\n",
|
|
" <td>175</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>남</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>179</td>\n",
|
|
" <td>270</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>4</th>\n",
|
|
" <td>175</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>6</td>\n",
|
|
" <td>동</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>...</th>\n",
|
|
" <td>...</td>\n",
|
|
" <td>...</td>\n",
|
|
" <td>...</td>\n",
|
|
" <td>...</td>\n",
|
|
" <td>...</td>\n",
|
|
" <td>...</td>\n",
|
|
" <td>...</td>\n",
|
|
" <td>...</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>59</th>\n",
|
|
" <td>210</td>\n",
|
|
" <td>4</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>남</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>180</td>\n",
|
|
" <td>270</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>60</th>\n",
|
|
" <td>211</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>6</td>\n",
|
|
" <td>동</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>61</th>\n",
|
|
" <td>211</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>동</td>\n",
|
|
" <td>270</td>\n",
|
|
" <td>090</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>62</th>\n",
|
|
" <td>211</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>17</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>63</th>\n",
|
|
" <td>211</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>18</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" </tbody>\n",
|
|
"</table>\n",
|
|
"<p>64 rows × 8 columns</p>\n",
|
|
"</div>"
|
|
],
|
|
"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 북 남 NaN NaN\n",
|
|
"2 175 2 A 7 북 동 NaN NaN\n",
|
|
"3 175 2 B 3 남 서 179 270\n",
|
|
"4 175 3 A 6 동 서 NaN NaN\n",
|
|
".. ... ... ... ... ... ... ... ...\n",
|
|
"59 210 4 B 3 남 서 180 270\n",
|
|
"60 211 1 A 6 동 서 NaN NaN\n",
|
|
"61 211 1 B 2 서 동 270 090\n",
|
|
"62 211 2 A 17 NaN NaN NaN NaN\n",
|
|
"63 211 2 B 18 NaN NaN NaN NaN\n",
|
|
"\n",
|
|
"[64 rows x 8 columns]"
|
|
]
|
|
},
|
|
"execution_count": 6,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"# [방위각정보] 불러오기 및 병합\n",
|
|
"angle = pd.read_csv('../../Data/tables/angle.csv', index_col=0)\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": 7,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<div>\n",
|
|
"<style scoped>\n",
|
|
" .dataframe tbody tr th:only-of-type {\n",
|
|
" vertical-align: middle;\n",
|
|
" }\n",
|
|
"\n",
|
|
" .dataframe tbody tr th {\n",
|
|
" vertical-align: top;\n",
|
|
" }\n",
|
|
"\n",
|
|
" .dataframe thead th {\n",
|
|
" text-align: right;\n",
|
|
" }\n",
|
|
"</style>\n",
|
|
"<table border=\"1\" class=\"dataframe\">\n",
|
|
" <thead>\n",
|
|
" <tr style=\"text-align: right;\">\n",
|
|
" <th></th>\n",
|
|
" <th>inter_no</th>\n",
|
|
" <th>node_id</th>\n",
|
|
" <th>move_no</th>\n",
|
|
" <th>inc_edge</th>\n",
|
|
" <th>out_edge</th>\n",
|
|
" </tr>\n",
|
|
" </thead>\n",
|
|
" <tbody>\n",
|
|
" <tr>\n",
|
|
" <th>0</th>\n",
|
|
" <td>175</td>\n",
|
|
" <td>i0</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>1</th>\n",
|
|
" <td>175</td>\n",
|
|
" <td>i0</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>571510153_02</td>\n",
|
|
" <td>571545870_01</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>2</th>\n",
|
|
" <td>175</td>\n",
|
|
" <td>i0</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>-571542797_02</td>\n",
|
|
" <td>571510153_01</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>3</th>\n",
|
|
" <td>175</td>\n",
|
|
" <td>i0</td>\n",
|
|
" <td>4</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>4</th>\n",
|
|
" <td>175</td>\n",
|
|
" <td>i0</td>\n",
|
|
" <td>5</td>\n",
|
|
" <td>571510153_02</td>\n",
|
|
" <td>571500487_01</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>5</th>\n",
|
|
" <td>175</td>\n",
|
|
" <td>i0</td>\n",
|
|
" <td>6</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>6</th>\n",
|
|
" <td>175</td>\n",
|
|
" <td>i0</td>\n",
|
|
" <td>7</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>7</th>\n",
|
|
" <td>175</td>\n",
|
|
" <td>i0</td>\n",
|
|
" <td>8</td>\n",
|
|
" <td>-571542797_02</td>\n",
|
|
" <td>571500487_01</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>8</th>\n",
|
|
" <td>176</td>\n",
|
|
" <td>i1</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>-571542810_01</td>\n",
|
|
" <td>571543469_01</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>9</th>\n",
|
|
" <td>176</td>\n",
|
|
" <td>i1</td>\n",
|
|
" <td>4</td>\n",
|
|
" <td>571542797_02.99</td>\n",
|
|
" <td>571542810_01</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>10</th>\n",
|
|
" <td>176</td>\n",
|
|
" <td>i1</td>\n",
|
|
" <td>5</td>\n",
|
|
" <td>571543469_02</td>\n",
|
|
" <td>-571542797_02.99</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>11</th>\n",
|
|
" <td>176</td>\n",
|
|
" <td>i1</td>\n",
|
|
" <td>8</td>\n",
|
|
" <td>-571542810_01</td>\n",
|
|
" <td>-571542797_02.99</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>12</th>\n",
|
|
" <td>176</td>\n",
|
|
" <td>i1</td>\n",
|
|
" <td>8</td>\n",
|
|
" <td>-571542810_01</td>\n",
|
|
" <td>-571542797_02.99</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>13</th>\n",
|
|
" <td>176</td>\n",
|
|
" <td>i1</td>\n",
|
|
" <td>18</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>14</th>\n",
|
|
" <td>177</td>\n",
|
|
" <td>i2</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>15</th>\n",
|
|
" <td>177</td>\n",
|
|
" <td>i2</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>-571542809_01</td>\n",
|
|
" <td>571542809_01</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>16</th>\n",
|
|
" <td>177</td>\n",
|
|
" <td>i2</td>\n",
|
|
" <td>4</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>17</th>\n",
|
|
" <td>177</td>\n",
|
|
" <td>i2</td>\n",
|
|
" <td>5</td>\n",
|
|
" <td>-571542809_01</td>\n",
|
|
" <td>571542811_01</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>18</th>\n",
|
|
" <td>177</td>\n",
|
|
" <td>i2</td>\n",
|
|
" <td>7</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>19</th>\n",
|
|
" <td>177</td>\n",
|
|
" <td>i2</td>\n",
|
|
" <td>8</td>\n",
|
|
" <td>-571542809_01</td>\n",
|
|
" <td>571542811_01</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>20</th>\n",
|
|
" <td>177</td>\n",
|
|
" <td>i2</td>\n",
|
|
" <td>17</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>21</th>\n",
|
|
" <td>177</td>\n",
|
|
" <td>i2</td>\n",
|
|
" <td>18</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>22</th>\n",
|
|
" <td>178</td>\n",
|
|
" <td>i3</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>23</th>\n",
|
|
" <td>178</td>\n",
|
|
" <td>i3</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>571540303_02.21</td>\n",
|
|
" <td>571500475_01</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>24</th>\n",
|
|
" <td>178</td>\n",
|
|
" <td>i3</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>571540304_02</td>\n",
|
|
" <td>571540303_01</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>25</th>\n",
|
|
" <td>178</td>\n",
|
|
" <td>i3</td>\n",
|
|
" <td>4</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>26</th>\n",
|
|
" <td>178</td>\n",
|
|
" <td>i3</td>\n",
|
|
" <td>5</td>\n",
|
|
" <td>571540303_02.21</td>\n",
|
|
" <td>571556450_01</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>27</th>\n",
|
|
" <td>178</td>\n",
|
|
" <td>i3</td>\n",
|
|
" <td>6</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>28</th>\n",
|
|
" <td>178</td>\n",
|
|
" <td>i3</td>\n",
|
|
" <td>7</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>29</th>\n",
|
|
" <td>178</td>\n",
|
|
" <td>i3</td>\n",
|
|
" <td>8</td>\n",
|
|
" <td>571540304_02</td>\n",
|
|
" <td>571556450_01</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>30</th>\n",
|
|
" <td>201</td>\n",
|
|
" <td>i8</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>31</th>\n",
|
|
" <td>201</td>\n",
|
|
" <td>i8</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>571500618_02</td>\n",
|
|
" <td>571500617_01</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>32</th>\n",
|
|
" <td>201</td>\n",
|
|
" <td>i8</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>571500618_02</td>\n",
|
|
" <td>571500617_01</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>33</th>\n",
|
|
" <td>201</td>\n",
|
|
" <td>i8</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>-571500569_01</td>\n",
|
|
" <td>571500618_01</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>34</th>\n",
|
|
" <td>201</td>\n",
|
|
" <td>i8</td>\n",
|
|
" <td>4</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>35</th>\n",
|
|
" <td>201</td>\n",
|
|
" <td>i8</td>\n",
|
|
" <td>5</td>\n",
|
|
" <td>571500618_02</td>\n",
|
|
" <td>571500583_02</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>36</th>\n",
|
|
" <td>201</td>\n",
|
|
" <td>i8</td>\n",
|
|
" <td>6</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>37</th>\n",
|
|
" <td>201</td>\n",
|
|
" <td>i8</td>\n",
|
|
" <td>6</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>38</th>\n",
|
|
" <td>201</td>\n",
|
|
" <td>i8</td>\n",
|
|
" <td>7</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>39</th>\n",
|
|
" <td>201</td>\n",
|
|
" <td>i8</td>\n",
|
|
" <td>8</td>\n",
|
|
" <td>-571500569_01</td>\n",
|
|
" <td>571500583_02</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>40</th>\n",
|
|
" <td>202</td>\n",
|
|
" <td>i9</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>571510152_01</td>\n",
|
|
" <td>571510152_01.65</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>41</th>\n",
|
|
" <td>202</td>\n",
|
|
" <td>i9</td>\n",
|
|
" <td>6</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>42</th>\n",
|
|
" <td>202</td>\n",
|
|
" <td>i9</td>\n",
|
|
" <td>17</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>43</th>\n",
|
|
" <td>202</td>\n",
|
|
" <td>i9</td>\n",
|
|
" <td>18</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>44</th>\n",
|
|
" <td>206</td>\n",
|
|
" <td>i7</td>\n",
|
|
" <td>4</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>45</th>\n",
|
|
" <td>206</td>\n",
|
|
" <td>i7</td>\n",
|
|
" <td>4</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>46</th>\n",
|
|
" <td>206</td>\n",
|
|
" <td>i7</td>\n",
|
|
" <td>8</td>\n",
|
|
" <td>-571511538_02</td>\n",
|
|
" <td>571542073_02</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>47</th>\n",
|
|
" <td>206</td>\n",
|
|
" <td>i7</td>\n",
|
|
" <td>8</td>\n",
|
|
" <td>-571511538_02</td>\n",
|
|
" <td>571542073_02</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>48</th>\n",
|
|
" <td>206</td>\n",
|
|
" <td>i7</td>\n",
|
|
" <td>17</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>49</th>\n",
|
|
" <td>206</td>\n",
|
|
" <td>i7</td>\n",
|
|
" <td>17</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>50</th>\n",
|
|
" <td>206</td>\n",
|
|
" <td>i7</td>\n",
|
|
" <td>18</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>51</th>\n",
|
|
" <td>206</td>\n",
|
|
" <td>i7</td>\n",
|
|
" <td>18</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>52</th>\n",
|
|
" <td>210</td>\n",
|
|
" <td>i6</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>571500535_02.18</td>\n",
|
|
" <td>571542115_01</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>53</th>\n",
|
|
" <td>210</td>\n",
|
|
" <td>i6</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>571500585_02</td>\n",
|
|
" <td>571500535_01</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>54</th>\n",
|
|
" <td>210</td>\n",
|
|
" <td>i6</td>\n",
|
|
" <td>4</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>55</th>\n",
|
|
" <td>210</td>\n",
|
|
" <td>i6</td>\n",
|
|
" <td>5</td>\n",
|
|
" <td>571500535_02.18</td>\n",
|
|
" <td>571511538_01</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>56</th>\n",
|
|
" <td>210</td>\n",
|
|
" <td>i6</td>\n",
|
|
" <td>6</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>57</th>\n",
|
|
" <td>210</td>\n",
|
|
" <td>i6</td>\n",
|
|
" <td>7</td>\n",
|
|
" <td>571511538_02.121</td>\n",
|
|
" <td>571542115_01</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>58</th>\n",
|
|
" <td>210</td>\n",
|
|
" <td>i6</td>\n",
|
|
" <td>8</td>\n",
|
|
" <td>571500585_02</td>\n",
|
|
" <td>571511538_01</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>59</th>\n",
|
|
" <td>210</td>\n",
|
|
" <td>i6</td>\n",
|
|
" <td>18</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" </tbody>\n",
|
|
"</table>\n",
|
|
"</div>"
|
|
],
|
|
"text/plain": [
|
|
" inter_no node_id move_no inc_edge out_edge\n",
|
|
"0 175 i0 1 NaN NaN\n",
|
|
"1 175 i0 2 571510153_02 571545870_01\n",
|
|
"2 175 i0 3 -571542797_02 571510153_01\n",
|
|
"3 175 i0 4 NaN NaN\n",
|
|
"4 175 i0 5 571510153_02 571500487_01\n",
|
|
"5 175 i0 6 NaN NaN\n",
|
|
"6 175 i0 7 NaN NaN\n",
|
|
"7 175 i0 8 -571542797_02 571500487_01\n",
|
|
"8 176 i1 3 -571542810_01 571543469_01\n",
|
|
"9 176 i1 4 571542797_02.99 571542810_01\n",
|
|
"10 176 i1 5 571543469_02 -571542797_02.99\n",
|
|
"11 176 i1 8 -571542810_01 -571542797_02.99\n",
|
|
"12 176 i1 8 -571542810_01 -571542797_02.99\n",
|
|
"13 176 i1 18 NaN NaN\n",
|
|
"14 177 i2 1 NaN NaN\n",
|
|
"15 177 i2 3 -571542809_01 571542809_01\n",
|
|
"16 177 i2 4 NaN NaN\n",
|
|
"17 177 i2 5 -571542809_01 571542811_01\n",
|
|
"18 177 i2 7 NaN NaN\n",
|
|
"19 177 i2 8 -571542809_01 571542811_01\n",
|
|
"20 177 i2 17 NaN NaN\n",
|
|
"21 177 i2 18 NaN NaN\n",
|
|
"22 178 i3 1 NaN NaN\n",
|
|
"23 178 i3 2 571540303_02.21 571500475_01\n",
|
|
"24 178 i3 3 571540304_02 571540303_01\n",
|
|
"25 178 i3 4 NaN NaN\n",
|
|
"26 178 i3 5 571540303_02.21 571556450_01\n",
|
|
"27 178 i3 6 NaN NaN\n",
|
|
"28 178 i3 7 NaN NaN\n",
|
|
"29 178 i3 8 571540304_02 571556450_01\n",
|
|
"30 201 i8 1 NaN NaN\n",
|
|
"31 201 i8 2 571500618_02 571500617_01\n",
|
|
"32 201 i8 2 571500618_02 571500617_01\n",
|
|
"33 201 i8 3 -571500569_01 571500618_01\n",
|
|
"34 201 i8 4 NaN NaN\n",
|
|
"35 201 i8 5 571500618_02 571500583_02\n",
|
|
"36 201 i8 6 NaN NaN\n",
|
|
"37 201 i8 6 NaN NaN\n",
|
|
"38 201 i8 7 NaN NaN\n",
|
|
"39 201 i8 8 -571500569_01 571500583_02\n",
|
|
"40 202 i9 2 571510152_01 571510152_01.65\n",
|
|
"41 202 i9 6 NaN NaN\n",
|
|
"42 202 i9 17 NaN NaN\n",
|
|
"43 202 i9 18 NaN NaN\n",
|
|
"44 206 i7 4 NaN NaN\n",
|
|
"45 206 i7 4 NaN NaN\n",
|
|
"46 206 i7 8 -571511538_02 571542073_02\n",
|
|
"47 206 i7 8 -571511538_02 571542073_02\n",
|
|
"48 206 i7 17 NaN NaN\n",
|
|
"49 206 i7 17 NaN NaN\n",
|
|
"50 206 i7 18 NaN NaN\n",
|
|
"51 206 i7 18 NaN NaN\n",
|
|
"52 210 i6 2 571500535_02.18 571542115_01\n",
|
|
"53 210 i6 3 571500585_02 571500535_01\n",
|
|
"54 210 i6 4 NaN NaN\n",
|
|
"55 210 i6 5 571500535_02.18 571511538_01\n",
|
|
"56 210 i6 6 NaN NaN\n",
|
|
"57 210 i6 7 571511538_02.121 571542115_01\n",
|
|
"58 210 i6 8 571500585_02 571511538_01\n",
|
|
"59 210 i6 18 NaN NaN"
|
|
]
|
|
},
|
|
"execution_count": 7,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"# [네트워크], [교차로-노드 매칭], [교차로정보] 불러오기 \n",
|
|
"net = sumolib.net.readNet('../../Data/networks/SN_sample.net.xml')\n",
|
|
"inter_node = pd.read_csv('../../Data/tables/inter_node.csv', index_col=0)\n",
|
|
"inter_info = pd.read_csv('../../Data/tables/inter_info.csv', index_col=0)\n",
|
|
"\n",
|
|
"inter_node1 = inter_node[inter_node.inter_type == 'parent'].drop('inter_type', axis=1)\n",
|
|
"inter_info1 = inter_info[['inter_no', 'inter_lat', 'inter_lon']]\n",
|
|
"inter = pd.merge(inter_node1, inter_info1, how='left', left_on=['inter_no'],\n",
|
|
" right_on=['inter_no']).drop_duplicates()\n",
|
|
"\n",
|
|
"inter2node = dict(zip(inter['inter_no'], inter['node_id']))\n",
|
|
"\n",
|
|
"match5 = match4.copy()\n",
|
|
"# 진입진출ID 매칭\n",
|
|
"for index, row in match5.iterrows():\n",
|
|
" node_id = inter2node[row.inter_no]\n",
|
|
" node = net.getNode(node_id)\n",
|
|
" # 교차로의 모든 (from / to) edges\n",
|
|
" inc_edges = [edge for edge in node.getIncoming() if edge.getFunction() == ''] # incoming edges\n",
|
|
" out_edges = [edge for edge in node.getOutgoing() if edge.getFunction() == ''] # outgoing edges\n",
|
|
" # 교차로의 모든 (from / to) directions\n",
|
|
" inc_dirs = []\n",
|
|
" for inc_edge in inc_edges:\n",
|
|
" start = inc_edge.getShape()[-2]\n",
|
|
" end = inc_edge.getShape()[-1]\n",
|
|
" inc_dir = np.array(end) - np.array(start)\n",
|
|
" inc_dir = inc_dir / (inc_dir ** 2).sum() ** 0.5\n",
|
|
" inc_dirs.append(inc_dir)\n",
|
|
" out_dirs = []\n",
|
|
" for out_edge in out_edges:\n",
|
|
" start = out_edge.getShape()[0]\n",
|
|
" end = out_edge.getShape()[1]\n",
|
|
" out_dir = np.array(end) - np.array(start)\n",
|
|
" out_dir = out_dir / (out_dir ** 2).sum() ** 0.5\n",
|
|
" out_dirs.append(out_dir)\n",
|
|
" # 진입각, 진출각 불러오기\n",
|
|
" if not pd.isna(row.inc_angle):\n",
|
|
" inc_angle = int(row.inc_angle)\n",
|
|
" out_angle = int(row.out_angle)\n",
|
|
" # 방위각을 일반각으로 가공, 라디안 변환, 단위벡터로 변환\n",
|
|
" inc_angle = (-90 - inc_angle) % 360\n",
|
|
" inc_angle = inc_angle * np.pi / 180.\n",
|
|
" inc_dir_true = np.array([np.cos(inc_angle), np.sin(inc_angle)])\n",
|
|
" out_angle = (90 - out_angle) % 360\n",
|
|
" out_angle = out_angle * np.pi / 180.\n",
|
|
" out_dir_true = np.array([np.cos(out_angle), np.sin(out_angle)])\n",
|
|
" # 매칭 엣지 반환\n",
|
|
" inc_index = np.array([np.dot(inc_dir, inc_dir_true) for inc_dir in inc_dirs]).argmax()\n",
|
|
" out_index = np.array([np.dot(out_dir, out_dir_true) for out_dir in out_dirs]).argmax()\n",
|
|
" inc_edge_id = inc_edges[inc_index].getID()\n",
|
|
" out_edge_id = out_edges[out_index].getID()\n",
|
|
" match5.at[index, 'inc_edge'] = inc_edge_id\n",
|
|
" match5.at[index, 'out_edge'] = out_edge_id\n",
|
|
"match5['node_id'] = match5['inter_no'].map(inter2node)\n",
|
|
"match5 = match5[['inter_no', 'node_id', 'move_no', 'inc_edge', 'out_edge']]\n",
|
|
"match5 = match5.sort_values(by=['inter_no', 'move_no']).reset_index(drop=True)\n",
|
|
"match5[:60]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# 2. 이력 + 이동류"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 8,
|
|
"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",
|
|
"times = range(midnight, next_day, 5)\n",
|
|
"time = random.choice(times)\n",
|
|
"time2move = dict(zip(times,moves))\n",
|
|
"history = pd.read_csv('../../Data/tables/history.csv', index_col=0)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 56,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"time2movement = {}\n",
|
|
"for time in times:\n",
|
|
" # 1. 상태 테이블 조회해서 전체 데이터중 필요데이터(교차로번호, A링 현시번호, A링 이동류번호, B링 현시번호, B링 이동류번호)만 수집 : A\n",
|
|
" move = time2move[time]\n",
|
|
" # 2. 이력 테이블 조회해서 교차로별로 유닉스시간 최대인 데이터(교차로변호, 종료유닉스타임)만 수집 : B\n",
|
|
" recent_histories = [group.iloc[-1:] for _, group in history[history['end_unix'] < time].groupby('inter_no')]\n",
|
|
" if not recent_histories:\n",
|
|
" recent_history = pd.DataFrame({'inter_no':[], 'end_unix':[]})\n",
|
|
" else:\n",
|
|
" recent_history = pd.concat(recent_histories)\n",
|
|
" recent_unix = recent_history[['inter_no', 'end_unix']]\n",
|
|
" # 3. 상태 테이블 조회정보(A)와 이력 테이블 조회정보(B) 조인(키값 : 교차로번호) : C\n",
|
|
" move = pd.merge(move, recent_unix, how='left', left_on='inter_no', right_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):\n",
|
|
" pass\n",
|
|
" else:\n",
|
|
" movement = pd.DataFrame()\n",
|
|
" except NameError:\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 > time - 3600]\n",
|
|
" movement = movement.sort_values(by=['start_unix','inter_no','phas_A','phas_B']).reset_index(drop=True)\n",
|
|
" time2movement[time] = movement\n",
|
|
"del movement"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 64,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"17280"
|
|
]
|
|
},
|
|
"execution_count": 64,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"len(times)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 84,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"1704380900\n",
|
|
"94\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"k=100\n",
|
|
"print(times[k])\n",
|
|
"print(len(time2movement[times[k]]))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 85,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"[<matplotlib.lines.Line2D at 0x2b128b978e0>]"
|
|
]
|
|
},
|
|
"execution_count": 85,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
},
|
|
{
|
|
"data": {
|
|
"image/png": "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+OCDwpUrVySvuXTpkjBixAjB19dXaN68ufDyyy+LU1w1du7cKfTo0UPw8vISbr31VmH58uV61/7kk0+E1q1bC15eXkLfvn2Fffv2SY6bUpebgfZ3tHPnTgGAwcfFixfF1/A7sh9zAxRB4PdjT4a+n5SUFKFVq1aCn5+foFAohD179kiO8z5kHpkgCILj2m+IiIiI9LnsGBQiIiJquhigEBERkdNhgEJEREROhwEKEREROR0GKEREROR0GKAQERGR02GAQkRERE6HAQoREZETeffdd9G/f3/4+fnprRptjEwmM/j44IMPxDIFBQUYPXo05HI5goODMX78eJSUlBg837lz5xAYGGjy9bUdOnQId999N4KDgxEaGoqJEycavU59GKAQERHZ2Z133okVK1YYPFZZWYmHH34Yzz33nMnnu3LliuTxzTffQCaTISkpSSwzevRonDhxAqmpqdiwYQN2796NiRMn6p2rqqoKo0aNwqBBg8x+X7m5uYiPj0eHDh2QkZGBLVu24MSJE3jqqafMPpdLpLonIiJqSu644w6DywxoW758uRAUFNSo899///3CkCFDxO2TJ08KAIQDBw6I+zZv3izIZDLhr7/+krz21VdfFZ544gmj1//qq6+E6OhowdvbW+jUqZOwZMkS8dgXX3whhIWFCTU1NeK+Y8eOCQCEs2fPmvUe2IJCRETUhOTl5WHjxo0YP368uC89PR3BwcHo06ePuC8+Ph5ubm7IyMgQ9+3YsQNr167FkiVLDJ571apVmDVrFt59912cOnUK7733HmbOnImVK1cCACoqKuDl5QU3t7rwwtfXFwDw22+/mfU+GKAQERE1IStXrkRgYCBGjhwp7lMqlQgLC5OU8/DwQEhICJRKJQDgn3/+wVNPPYUVK1ZALpcbPPfs2bPx4YcfYuTIkWjXrh1GjhyJKVOm4IsvvgAADBkyBEqlEh988AEqKytx7do1vP766wBqu6HMwQCFiIjIxt577z0EBASIjz179uDZZ5+V7MvJybHKtb755huMHj0aPj4+Zr1uwoQJePzxxzF48GCDx0tLS3H+/HmMHz9eUu933nkH58+fBwB06dIFK1euxIcffgg/Pz9ERESgXbt2CA8Pl7SqmMLDrNJERERktmeffRaPPPKIuD169GgkJSVJWjkiIyMtvs6ePXuQnZ2N77//XrI/IiIC+fn5kn3V1dUoKChAREQEgNrunfXr12PBggUAAEEQoFar4eHhgS+//BKJiYkAgK+++gpxcXGSc7m7u4vPH3/8cTz++OPIy8uDv78/ZDIZFi5ciFtvvdWs98IAhYiIyMZCQkIQEhIibvv6+iIsLAwdOnSw6nWWLVuG3r17o3v37pL9CoUChYWFyMzMRO/evQHUBiRqtVoMNtLT01FTUyO+5ueff8b777+PvXv34pZbbkGzZs0QGRmJCxcuYPTo0Q3WJTw8HEBti46Pjw/uvvtus94LAxQiIiInkpOTg4KCAuTk5KCmpgZHjhwBAHTo0AEBAQEAgOjoaKSkpODBBx8UX6dSqbB27Vp8+OGHeufs3Lkzhg8fjgkTJmDp0qWoqqrCpEmT8Nhjj4ktN507d5a85uDBg3Bzc0PXrl3FfW+//TZefPFFBAUFYfjw4aioqMDBgwdx7do1TJ06FQDw6aefon///ggICEBqaiqmTZuGefPmmZ1ThQEKERGRE5k1a5Y4KwYAevbsCQDYuXMn7rzzTgBAdnY2ioqKJK9bs2YNBEHAqFGjDJ531apVmDRpEoYOHQo3NzckJSVh8eLFZtXtmWeegZ+fHz744ANMmzYN/v7+iI2NxeTJk8Uy+/fvx+zZs1FSUoLo6Gh88cUXGDNmjFnXAQCZIAiC2a8iIiIisiHO4iEiIiKnwwCFiIiInA4DFCIiInI6DFCIiIjI6TBAISIiIqfDAIWIiIicDgMUIiIicjoMUIiIiMjpMEAhIiIip8MAhYiIiJwOAxQiIiJyOgxQiIiIyOn8P2Vzdi88E0D1AAAAAElFTkSuQmCC",
|
|
"text/plain": [
|
|
"<Figure size 640x480 with 1 Axes>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"lengths = [len(time2movement[time]) for time in times]\n",
|
|
"import matplotlib.pyplot as plt\n",
|
|
"plt.plot(times,lengths)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 88,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<div>\n",
|
|
"<style scoped>\n",
|
|
" .dataframe tbody tr th:only-of-type {\n",
|
|
" vertical-align: middle;\n",
|
|
" }\n",
|
|
"\n",
|
|
" .dataframe tbody tr th {\n",
|
|
" vertical-align: top;\n",
|
|
" }\n",
|
|
"\n",
|
|
" .dataframe thead th {\n",
|
|
" text-align: right;\n",
|
|
" }\n",
|
|
"</style>\n",
|
|
"<table border=\"1\" class=\"dataframe\">\n",
|
|
" <thead>\n",
|
|
" <tr style=\"text-align: right;\">\n",
|
|
" <th></th>\n",
|
|
" <th>inter_no</th>\n",
|
|
" <th>phas_A</th>\n",
|
|
" <th>phas_B</th>\n",
|
|
" <th>move_A</th>\n",
|
|
" <th>move_B</th>\n",
|
|
" <th>start_unix</th>\n",
|
|
" </tr>\n",
|
|
" </thead>\n",
|
|
" <tbody>\n",
|
|
" <tr>\n",
|
|
" <th>0</th>\n",
|
|
" <td>206</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>8</td>\n",
|
|
" <td>4</td>\n",
|
|
" <td>1704381841</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>1</th>\n",
|
|
" <td>206</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>17</td>\n",
|
|
" <td>18</td>\n",
|
|
" <td>1704381841</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>2</th>\n",
|
|
" <td>206</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>8</td>\n",
|
|
" <td>4</td>\n",
|
|
" <td>1704381841</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>3</th>\n",
|
|
" <td>206</td>\n",
|
|
" <td>4</td>\n",
|
|
" <td>4</td>\n",
|
|
" <td>17</td>\n",
|
|
" <td>18</td>\n",
|
|
" <td>1704381841</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>4</th>\n",
|
|
" <td>211</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>6</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>1704381845</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>...</th>\n",
|
|
" <td>...</td>\n",
|
|
" <td>...</td>\n",
|
|
" <td>...</td>\n",
|
|
" <td>...</td>\n",
|
|
" <td>...</td>\n",
|
|
" <td>...</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>643</th>\n",
|
|
" <td>206</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>8</td>\n",
|
|
" <td>4</td>\n",
|
|
" <td>1704385320</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>644</th>\n",
|
|
" <td>211</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>6</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>1704385325</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>645</th>\n",
|
|
" <td>211</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>17</td>\n",
|
|
" <td>18</td>\n",
|
|
" <td>1704385325</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>646</th>\n",
|
|
" <td>177</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>8</td>\n",
|
|
" <td>4</td>\n",
|
|
" <td>1704385350</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>647</th>\n",
|
|
" <td>177</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>7</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>1704385350</td>\n",
|
|
" </tr>\n",
|
|
" </tbody>\n",
|
|
"</table>\n",
|
|
"<p>648 rows × 6 columns</p>\n",
|
|
"</div>"
|
|
],
|
|
"text/plain": [
|
|
" inter_no phas_A phas_B move_A move_B start_unix\n",
|
|
"0 206 1 1 8 4 1704381841\n",
|
|
"1 206 2 2 17 18 1704381841\n",
|
|
"2 206 3 3 8 4 1704381841\n",
|
|
"3 206 4 4 17 18 1704381841\n",
|
|
"4 211 1 1 6 2 1704381845\n",
|
|
".. ... ... ... ... ... ...\n",
|
|
"643 206 3 3 8 4 1704385320\n",
|
|
"644 211 1 1 6 2 1704385325\n",
|
|
"645 211 2 2 17 18 1704385325\n",
|
|
"646 177 1 1 8 4 1704385350\n",
|
|
"647 177 2 2 7 3 1704385350\n",
|
|
"\n",
|
|
"[648 rows x 6 columns]"
|
|
]
|
|
},
|
|
"execution_count": 88,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"time2movement[times[1000]]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"J=0\n",
|
|
"for time in times:\n",
|
|
" # 1. 상태 테이블 조회해서 전체 데이터중 필요데이터(교차로번호, A링 현시번호, A링 이동류번호, B링 현시번호, B링 이동류번호)만 수집 : A\n",
|
|
" move = time2move[time]\n",
|
|
" # 2. 이력 테이블 조회해서 교차로별로 유닉스시간 최대인 데이터(교차로변호, 종료유닉스타임)만 수집 : B\n",
|
|
" recent_histories = [group.iloc[-1:] for _, group in history[history['end_unix'] < time].groupby('inter_no')]\n",
|
|
" if not recent_histories:\n",
|
|
" recent_history = pd.DataFrame({'inter_no':[], 'end_unix':[]})\n",
|
|
" else:\n",
|
|
" recent_history = pd.concat(recent_histories)\n",
|
|
" recent_unix = recent_history[['inter_no', 'end_unix']]\n",
|
|
" # 3. 상태 테이블 조회정보(A)와 이력 테이블 조회정보(B) 조인(키값 : 교차로번호) : C\n",
|
|
" move = pd.merge(move, recent_unix, how='left', left_on='inter_no', right_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):\n",
|
|
" pass\n",
|
|
" else:\n",
|
|
" movement = pd.DataFrame()\n",
|
|
" except NameError:\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 > time - 3600]\n",
|
|
" movement = movement.sort_values(by=['start_unix','inter_no','phas_A','phas_B']).reset_index(drop=True)\n",
|
|
" if J % 10 == 0:\n",
|
|
" print(time)\n",
|
|
" # print('recent_unix', len(recent_histories))\n",
|
|
" # display(recent_unix)\n",
|
|
" # print('move')\n",
|
|
" # display(move)\n",
|
|
" # print('movement')\n",
|
|
" display(movement)\n",
|
|
" print(movement.start_unix.max() - movement.start_unix.min())\n",
|
|
" J += 1\n",
|
|
" if J == 1000:\n",
|
|
" break\n",
|
|
"del movement"
|
|
]
|
|
}
|
|
],
|
|
"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
|
|
}
|