# features計算過程紀錄 這份檔案用於紀錄各資料在資料處理中各階段的命名規則,避免過多版本時混淆。 ## 資料存放位置 [onedrive](https://1drv.ms/f/c/002d06ef873e3a00/EkeOXSUEem1Op399ZprSGbEBdspHKfZaxtVDORlChXFuDg?e=KAHVxe) ## 資料版本定義 ### 舉例 {數字:代表版本號,所有檔案按照此順序處理}. {檔案名稱} - {這個版本的檔案內容描述,包含簡述與欄位。} --- 1. 我是檔名 - 我是描述。 --- ### VD 1. merged_VD_all(原) - 從官網上抓下來的原始資料,未經任何處理直接合併為單個檔案。 - 欄位:`VDID, DataCollectTime, LinkID, LaneID, LaneType, Speed, Occupancy, VehicleType, Volume, VehicleSpeed` - `DataCollectTime`的`type`為`string` - freq:1分鐘一筆 2. vd_pre(原) - 只包含需要的日期跟VDID - 欄位:`VDID, DataCollectTime, LinkID, LaneID, LaneType, Speed, Occupancy, VehicleType, Volume, VehicleSpeed` - 包含缺失值(-99) - `DataCollectTime`的`type`為`datetime64[ns]` 3. vd_pre_no_-99_value(原) - 同`vd_pre`,但已經把`Speed, Occupancy, Volume, VehicleSpeed`中`-99`的數值設為`nan` 4. vd_pre_no_-99_no_dul(原) - 同`vd_pre_no_-99_value`,但刪除完全重複的row:透過對每個row計算hash,再根據hash刪除相同的row. - 多了一個欄位:`row_hash` - hash key: `0123456789abcdef` - type: `uint64` 5. vd_pre_5min(原) - 同`vd_pre_no_-99_no_dul` - 但把時間改為5分鐘1筆:假設時間為`1, 2, 3, 4, 5`,轉換成`5, 5, 5, 5, 5`。 - 新時間欄位直接取代舊時間欄位(`DataCollectTime`) 6. vd_features_v1(原) 1. vd_features_v1_spdavg - 欄位: `VDID, timestamp, weighted_avg` - 根據`vd_pre_5min`計算出`spdavg` 2. vd_features_v1_spdtrnd - 欄位: `VDID, timestamp, speed_diff` - 根據`vd_pre_5min`計算出`spdtrnd` 3. vd_features_v1_occ - 欄位: `VDID, timestamp, occ` - 根據`vd_pre_5min`計算出`occ` - pandas df - 欄位:`VDID, timestamp, spdavg, spdtrnd, occ` - 合併`6-1~6-3`後得到`vd_features_v1`. 7. vd_features_v1_flat(原) - pandas df - 把`vd_features_v1`展平,columns為`timestamp`, `feature_name * VDID`. - 欄位照:先`feature(spdavg, spdtrnd, occ)`,後`VDID`,由左至右排序。格式為`feature_VDID`,ex: `weighted_avg_VD-N1-N-18.010-M-LOOP` <!-- 8. vd_features_v1_flat_no_missed - 同`vd_features_v1_flat`,但把所有缺失的時間都補上,value為nan。 - ex: `20240101 00:30`在日期區間內,但`vd_pre_5min`找不到任何該時間的資料,則補上。 --> ### m05 1. merged_m05_all(原) - 從官網上抓下來的原始資料,未經任何處理直接合併為單個檔案。 - 欄位:`DataCollectTime`, `GantryFrom`, `GantryTo`, `VehicleType`, `Speed`, `Volume` - `DataCollectTime`的`type`為`string` - `GantryFrom`, `GantryTo`可能經過篩選,細節不明。 - freq:5分鐘一筆 2. m05_pre(原) - 只包含需要的日期跟GantryID(GantryTo, GantryFrom) - 欄位:`DataCollectTime`, `GantryFrom`, `GantryTo`, `VehicleType`, `Speed`, `Volume` - `DataCollectTime`的`type`為`datetime64[ns]` 3. m05_features_v1_spdavg(原) - pandas df - 根據m05_pre計算出spdavg - 欄位:`timestamp`, `GantryFrom`, `GantryTo`, `weighted_avg` 4. m05_specific_route_spdavg_flat_with_state - pandas df - 把`m05_features_v1_spdavg`展平,columns為`timestamp`, `spdavg * gantryIDs`. `gantryIDs`為一組門架代號,由兩個門架ID組成,格式為`GantryFrom-GantryTo`,ex: `01F0213N-01F0155N`. - 欄位照:<!-- 先`feature(spdavg)`,後 -->`gantryIDs`,由左至右排序。格式為`m05_spdavg_gantryIDs`,ex: `weighted_avg_01F0155S-01F0182S` - 從m05_features_v1_spdvag 取出我們要的路段('01F0248S', '01F0264S')後 算state, ttc, ttf 並改欄位名稱為 01F0248S_01F0264S_spdavg - 刪除假日資料 ### m06 1. M06A_months_parquet(原) - 內含12個檔名為`M06A_1.parquet`, `M06A_2.parquet`, ..., `M06A_12.parquet`的檔案,每個代表一個月分,合起來為2024年`m06a`的原始檔案parquet. - 欄位:`VehicleType`, `DetectionTimeO`, `GantryO`, `DetectionTimeD`, `GantryD`, `TripLength`, `TripEnd`, `Route` - 其中`DetectionTimeO`, `DetectionTimeD`的`type`為`str` 1. M06A_25100_S_up(原) - 代表篩選`M06A_months_parquet`中從南下(S)方向上(up)位於25.100K的交流道(台北交流道)的所有m06紀錄。 - 為整年份的檔案,未按月分檔。 - 25100代表交流道里程數,單位為m. - S代表南下或北上方向(N)。 - up代表上交流道或下交流道(down)。 - 另有`M06A_25100_S_down.parquet`, `M06A_25100_N_up.parquet`, `M06A_25100_N_down.parquet` - 時間精確到秒 - 欄位:`VehicleType`, `DetectionTimeO`, `GantryO`, `DetectionTimeD`, `GantryD`, `TripLength`, `TripEnd`, `Route` - 其中`DetectionTimeO`, `DetectionTimeD`的`type`為`str` - `dask` 2. M06A_25100_S_up_count(原) - 命名規則同`M06A_25100_S_up`,但記錄的是`groupby('DetectionTimeO').size()`或`groupby('DetectionTimeD').size()`. - 欄位:`DetectionTime`, `count`. - 其中`DetectionTime`的`type`為`datetime64[ns]` - 時間精確到5分鐘,轉換規則為:假設時間為`1, 2, 3, 4, 5`,轉換成`5, 5, 5, 5, 5`,忽略秒數,只看分鐘。 - 另有`M06A_25100_S_down_count.parquet`, `M06A_25100_N_up_count.parquet`, `M06A_25100_N_down_count.parquet`. - 篩除`DetectionTime`晚於`2024-12-31 23:55:00`或早於`2024-01-01 00:00:00`的資料。 - 資料為每5分鐘一筆,若無資料的時間自動把value設為0。 - `pandas` 3. M06A_25100_S_up_loc(原) - 同`M06A_25100_S_up_count`,但本資料是計算`groupby('GantryO').size()`或`groupby('GantryD').size()` - 欄位:`Gantry`, `count` 2. M06A_pre(原) - 只篩選出在`Route`中有包含需要門架(gantryID_v1)中的任何一個門架的紀錄 - 欄位:`VehicleType`, `DetectionTimeO`, `GantryO`, `DetectionTimeD`, `GantryD`, `TripLength`, `TripEnd`, `Route` - 其中`DetectionTimeO`, `DetectionTimeD`的type為`datetime64[ns]` 3. M06A_extract(原) - 把`Route`欄位的value按照需要門架(gantryID_v1)中的GantryID解析出時間,欄位名稱為`time_{GantryID}`, type為`datetime64[ns]`, ex: `time_01F0293N`. - 欄位:`Route`, `VehicleType`, `TripLength`, `time_{GantryID 1}`, ... 4. M06A_avgspeed_{GantryID 1}-{GantryID 2}(原) - pandas df - 從GantryID 1到GantryID 2平均行車速度 - 平均為每5min為一個時間區間,塞選其中符合條件的資料計算。 - 以endtime(GantryID 2的時間)決定屬於哪個時間區間。 - 假設時間為`1, 2, 3, 4, 5`,轉換成`5, 5, 5, 5, 5`。 - 欄位: `m06_avgspeed`, `timestamp` 5. M06A_feat_{GantryID 1}-{GantryID 2}(原) - 欄位: `timestamp`, `m06_state`, `m06_ttf`, `m06_ttc`, `m06_tag` - 計算traffic state、ttc、ttf(目前按照論文定義)。 - tag用於標示是否為`traffic state`(`m06_state`)狀態轉換的前後30分鐘。 <!-- ### 門架靜態資料 1. etag_distance - 來自eTag 配對路徑靜態資訊(v2.0),有各相鄰門架間的距離。 --> ## 合併成訓練資料 1. merged_37(原) - pandas df - 把`vd_features_v1_flat`、`m05_features_v1_flat`、`M06A_feat_01F0248S-01F0264S`根據時間合併。 - 以上三個檔案分別只讀取並使用以下欄位: - vd: `['VD-N1-S-23.900-M-LOOP', 'VD-N1-S-24.400-M-RS', 'VD-N1-S-25.440-N-LOOP', 'VD-N1-S-25.850-M-LOOP', 'VD-N1-S-26.350-M-RS', 'VD-N1-S-26.750-N-LOOP', 'VD-N1-S-28.840-M-RS']`的`['spdavg', 'spdtrnd', 'occ']` - m05: `['m05_spdavg_01F0248S-01F0264S']` - m06: `['m06_state', 'm06_ttf', 'm06_ttc', 'm06_ttf_no_upbound', 'm06_tag']` - 若有缺失值(nan),使用向前填充(`bfill`,例如0, nan, 9變成0, 9, 9)。 - 只篩選出時間在`2024-01-01 00:00:00`~`2024-12-31 23:59:59`,並確保每個時間都沒有nan. - 篩除週末,只保留週一到週五。 - 計算traffic state、ttc、ttf、tag - 欄位:[`spdavg_VD-N1-S-23.900-M-LOOP`,`spdtrnd_VD-N1-S-23.900-M-LOOP`,`occ_VD-N1-S-23.900-M-LOOP`,`spdavg_VD-N1-S-24.400-M-RS`,`spdtrnd_VD-N1-S-24.400-M-RS`,`occ_VD-N1-S-24.400-M-RS`,`spdavg_VD-N1-S-25.440-N-LOOP`,`spdtrnd_VD-N1-S-25.440-N-LOOP`,`occ_VD-N1-S-25.440-N-LOOP`,`spdavg_VD-N1-S-25.850-M-LOOP`,`spdtrnd_VD-N1-S-25.850-M-LOOP`,`occ_VD-N1-S-25.850-M-LOOP`,`spdavg_VD-N1-S-26.350-M-RS`,`spdtrnd_VD-N1-S-26.350-M-RS`,`occ_VD-N1-S-26.350-M-RS`,`spdavg_VD-N1-S-26.750-N-LOOP`,`spdtrnd_VD-N1-S-26.750-N-LOOP`,`occ_VD-N1-S-26.750-N-LOOP`,`spdavg_VD-N1-S-28.840-M-RS`,`spdtrnd_VD-N1-S-28.840-M-RS`,`occ_VD-N1-S-28.840-M-RS`,`m05_spdavg_01F0248S-01F0264S`,`m06_ttf`,`m06_ttc`,`m06_tag`] - index: 時間,`type`為`datetime64[ns]` 2. merged_37_5-10 * 從 merged_37 改,刪除 22.~5. 的資料 3. merged_m05_weekdays_only - 將vd 與 m05_flat_state 合併 - 刪除假日資料 4. merged_37_with_bins.csv * from: merged_37 * 依照 m05_spdavg_01F0248S-01F0264S,每 20 km 編號 (start from 0) 5. merged_37_cleaned - 將手動填充上去的資料刪除 6. merged_m06_m05 - 把m06 和 merged_m05_weekdays_only 合併 7. merged_37_state(原) - 與`merged_37`相同,但增加traffic state欄位(名稱:`m06_state`) - 欄位:`spdavg_VD-N1-S-23.900-M-LOOP`,`spdtrnd_VD-N1-S-23.900-M-LOOP`,`occ_VD-N1-S-23.900-M-LOOP`,`spdavg_VD-N1-S-24.400-M-RS`,`spdtrnd_VD-N1-S-24.400-M-RS`,`occ_VD-N1-S-24.400-M-RS`,`spdavg_VD-N1-S-25.440-N-LOOP`,`spdtrnd_VD-N1-S-25.440-N-LOOP`,`occ_VD-N1-S-25.440-N-LOOP`,`spdavg_VD-N1-S-25.850-M-LOOP`,`spdtrnd_VD-N1-S-25.850-M-LOOP`,`occ_VD-N1-S-25.850-M-LOOP`,`spdavg_VD-N1-S-26.350-M-RS`,`spdtrnd_VD-N1-S-26.350-M-RS`,`occ_VD-N1-S-26.350-M-RS`,`spdavg_VD-N1-S-26.750-N-LOOP`,`spdtrnd_VD-N1-S-26.750-N-LOOP`,`occ_VD-N1-S-26.750-N-LOOP`,`spdavg_VD-N1-S-28.840-M-RS`,`spdtrnd_VD-N1-S-28.840-M-RS`,`occ_VD-N1-S-28.840-M-RS`,`m05_spdavg_01F0248S-01F0264S`,`m06_state`,`m06_ttf`,`m06_ttc`,`m06_tag` 8. merged_37_plot - 與`merged_37_state`相同,但增加沒有上限的ttf欄位(名稱:`m06_ttf_no_upbound`),該欄位為未經"把超過37的設為37"處理,可用於分析平均塞車時間。 ## 參數定義 gantryID_v1: ``` gantry_id = ['01F0293N', '01F0256N', '01F0233N', '01F0213N', '01F0293S', '01F0264S', '01F0248S', '01F0182S']