---
# System prepended metadata

title: features計算過程紀錄

---

# 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']
