{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import os, random, sumolib\n", "import sumolib\n", "import pandas as pd\n", "import numpy as np\n", "from datetime import datetime" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "path_root = os.path.dirname(os.path.dirname(os.path.abspath('.')))\n", "path_dayplan = os.path.join(path_root, 'data', 'tables', '20240729', 'TC_IF_TOD_DAY_PLAN.csv')\n", "path_sigl_cycl = os.path.join(path_root, 'test_0729', 'data', 'tables', 'TL_IF_SIGL_CYCL.csv')\n", "dayplan = pd.read_csv(path_dayplan)\n", "CRSRD_IDs = [436, 437, 438, 442, 443, 455, 456, 457, 458]\n", "dayplan = dayplan[dayplan.CRSRD_ID.isin(CRSRD_IDs)]\n", "\n", "dayplan = dayplan.drop(columns=['LAST_MDFCN_DT'])" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "midnight = int(datetime(2024, 7, 29).timestamp())\n", "next_day = int(datetime(2024, 7, 30).timestamp())\n", "\n", "histories = []\n", "\n", "for CRSRD_ID in CRSRD_IDs:\n", " dplan = dayplan[dayplan.CRSRD_ID==CRSRD_ID]\n", " if ((dplan.HOUR==0) & (dplan.MIN==0)).any():\n", " pass\n", " else:\n", " dplan_temp = dplan[-1:]\n", " dplan_temp['HOUR'] = 0\n", " dplan_temp['MIN'] = 0\n", " dplan = pd.concat([dplan, dplan_temp])\n", " dplan = dplan.sort_values(by=['HOUR', 'MIN']).reset_index(drop=True)\n", " dplan.loc[:, 'end_unix'] = dplan['HOUR'].astype(int) * 3600 + dplan['MIN'].astype(int) * 60 + midnight\n", " history = []\n", " current_time = midnight\n", " for i in range(len(dplan)):\n", " row = dplan.iloc[i]\n", " cycle = row.CYCL\n", " offset = row.OFFSET\n", " unix_end = dplan.iloc[i+1]['end_unix'] if i < len(dplan) - 1 else next_day\n", " r = 0\n", " while current_time <= unix_end:\n", " remainder = current_time % 10\n", " if remainder != 0: # 현재시각의 일의자리가 0이 아니면 다음 현재시각의 일의자리가 0이 되도록 맞춰준다.\n", " r = (5 - remainder) % 10 - 5 # 1>-1, 2>-2, 3>-3, 4>-4, 5>-5, 6>4, 7>3, 8>2, 9>1\n", " else:\n", " r = random.choices([0, -1, 1], weights=[10, 1, 1])[0] # 측정오차\n", " # 0.001의 확률로 결측 발생\n", " if random.random() < 0.001: # 주기의 배수만큼 결측\n", " n = random.randint(0,100)\n", " current_time += n * cycle + r\n", " # 0.01의 확률로 이상치 발생\n", " elif random.random() > 0.99: # 카이제곱분포값 * 주기만큼의 이상치 발생. 카이제곱분포값은 항상 양수이고 평균이 1\n", " current_time += int(np.random.chisquare(df=1) * cycle) + r\n", " else:\n", " current_time += cycle + r # 결측/이상 없음\n", " new_row = row.copy()\n", " new_row['PHASE_DT'] = current_time\n", " new_row['CYCL'] = cycle\n", " new_row['OFFSET'] = offset\n", " history.append(new_row)\n", " history = pd.concat(history, axis=1).transpose()\n", " history = history[['PHASE_DT', 'CRSRD_ID']\n", " + [f'RING{alph}_PHASE{i}' for alph in ['A', 'B'] for i in range(1,9)]]\n", " history = history[history.PHASE_DT <= next_day]\n", " history = history.rename(columns={'PHASE_DT':'OCRN_DT'})\n", " histories.append(history)\n", "histories = pd.concat(histories)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "histories = histories.sort_values(by=['OCRN_DT', 'CRSRD_ID'])\n", "histories = histories.reset_index(drop=True)\n", "histories['FRST_REG_DT'] = ''\n", "histories['OCRN_DT'] = pd.to_datetime(histories['OCRN_DT'], unit='s')\n", "histories['OCRN_DT'] = histories['OCRN_DT'].dt.strftime('%Y-%m-%d %H:%M:%S.%f').str[:-3]\n", "histories.to_csv(path_sigl_cycl, index=False)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "c:\\github\\siggen\\test_0729\\data\\tables\\TL_IF_SIGL_CYCL.csv\n" ] } ], "source": [ "print(path_sigl_cycl)" ] } ], "metadata": { "kernelspec": { "display_name": "siggen_env", "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.12.4" } }, "nbformat": 4, "nbformat_minor": 2 }