# TPASS ## 資料分類 * 客運類:分成上車、下車資料,若下車資料皆非0數值,則為下車資料 * 府城客運:進上車站為0 => 先剔除資料 * 鐵路、捷運、微笑單車、輕軌:僅一筆資料,無法計算乘車時間 * 渡輪:僅一筆資料,無法計算乘車時間,上車皆為0、下車資料皆為1 * 漢程客運新營:有些上車為0,有些數據正常 => 先把上車為0的數據剔除 ![image](https://hackmd.io/_uploads/ByJTXq0k0.png) ![image](https://hackmd.io/_uploads/SkQLN9R1C.png) ## 問題 > 剔除duration為空值或為0的情況 > 剔除進上車站、出下車站相同的情況 * 運輸業者為空值 ![image](https://hackmd.io/_uploads/HJfn0uCJR.png) * 有些缺資料 ![image](https://hackmd.io/_uploads/SJew8tCkA.png) * 上錯車?? ![image](https://hackmd.io/_uploads/H1HCLFCJ0.png) ![image](https://hackmd.io/_uploads/SyBDtt01R.png) * 數據時間很短 ![image](https://hackmd.io/_uploads/rksH5KRyC.png) ![image](https://hackmd.io/_uploads/r1ijG9AyA.png) * 時間順序奇怪(但票卡序號是對的)(疑似是轉乘會出問題) ![image](https://hackmd.io/_uploads/SyUU4F0yR.png) ![image](https://hackmd.io/_uploads/B12q3tRk0.png) ![image](https://hackmd.io/_uploads/Hyr_pY0JR.png) ==>票卡序號是個人的刷卡順序,直接使用票卡序號排序計算時間 * 時間順序是對的,但票卡序號是錯的 ![image](https://hackmd.io/_uploads/Hygquc0yA.png) * 缺少數據導致計算錯誤 ![image](https://hackmd.io/_uploads/HkCtU5CyA.png) ![image](https://hackmd.io/_uploads/HJGYD5C1R.png) * 最久的有效時間 ![image](https://hackmd.io/_uploads/r18psqCkC.png) ![image](https://hackmd.io/_uploads/SkBSnqCyC.png) ![image](https://hackmd.io/_uploads/rkHi2cAyR.png) ==> 取4小時內為有效值,大於4小時者多為錯誤資料 * 時間很短,但是正確計算的數據 ![image](https://hackmd.io/_uploads/ryntpc010.png) ## CODE (merge_BUS_data.py) ```python= import pandas as pd import glob import time start_time = time.time() #選取資料夾內所有csv檔 file_paths = glob.glob(r'C:\NCKU\2024 travel behavior analysis - MeNGO\utf8\*.csv') dataframes = [] for file_path in file_paths: df = pd.read_csv(file_path, dtype={'交易日期': 'str','交易時間':'str','卡別': 'str','內碼':'str', '票卡序號': 'str','原始票價':'str','扣款金額': 'str','運輸業者':'str', '進上車站': 'str','出下車站':'str','交易類別': 'str','路線':'str', '備註': 'str'}) dataframes.append(df) # dataframe合併 dataframe = pd.concat(dataframes, ignore_index=True) dataframe['運輸業者'] = dataframe['運輸業者'].astype(str) #因為有些資料時間格式是53550,要在最前項補一位形成053550,才不會轉換出錯 dataframe['交易日期時間'] = pd.to_datetime(dataframe['交易日期'] + ' ' + dataframe['交易時間'].str.zfill(6), format='%Y/%m/%d %H%M%S', errors='coerce') dataframe = dataframe[['交易日期時間', '內碼', '票卡序號', '運輸業者', '進上車站', '出下車站', '路線']] # 剔除'運輸業者'為空值的data dataframe = dataframe.dropna(subset=['運輸業者']) # 剔除'運輸業者'包含鐵路、捷運、微笑單車、渡輪等字樣的data excluded_transport = ['鐵路', '捷運', '微笑單車', '渡輪','輕軌', '府城'] dataframe = dataframe[~dataframe['運輸業者'].str.contains('|'.join(excluded_transport))] # 使用票卡序號排序,取出相同內碼再將時間diff dataframe['票卡序號'] = dataframe['票卡序號'].astype(int) dataframe = dataframe.sort_values(by=['票卡序號']).reset_index(drop=True) dataframe['duration'] = dataframe.groupby('內碼')['交易日期時間'].diff() # 留下同時有進上車站、出下車站的列就好 dataframe = dataframe[dataframe['進上車站'].astype(int) != 0] dataframe = dataframe[dataframe['出下車站'].astype(int) != 0] # 剔除進上車站、出下車站相同的情況 dataframe = dataframe[dataframe['進上車站'] != dataframe['出下車站']] # 剔除duration為<=0、空值、>=4小時的數據 dataframe = dataframe[(dataframe['duration'] >= pd.Timedelta(0)) & (dataframe['duration'].notnull()) & (dataframe['duration'] <= pd.Timedelta(hours=4))] dataframe.to_csv('TPASS_BUS.csv', index=False, encoding='utf-8') end_time = time.time() print("execution_time: ", end_time - start_time, "秒") ``` ## 剔除完後的數據 > 656193筆 ![image](https://hackmd.io/_uploads/r1kHcoA10.png) ## 將整理過的數據與其他數據合併 ### code (merge_od_all.py) ```python= import pandas as pd import glob import time start_time = time.time() #選取資料夾內所有csv檔 file_paths = glob.glob(r'C:\NCKU\2024 travel behavior analysis - MeNGO\utf8\*.csv') dataframes = [] for file_path in file_paths: df = pd.read_csv(file_path, dtype={'交易日期': 'str','交易時間':'str','卡別': 'str','內碼':'str', '票卡序號': 'str','原始票價':'str','扣款金額': 'str','運輸業者':'str', '進上車站': 'str','出下車站':'str','交易類別': 'str','路線':'str', '備註': 'str'}) dataframes.append(df) # dataframe合併 dataframe = pd.concat(dataframes, ignore_index=True) dataframe = dataframe.dropna(subset=['運輸業者']) dataframe['交易日期時間'] = pd.to_datetime(dataframe['交易日期'] + ' ' + dataframe['交易時間'].str.zfill(6), format='%Y/%m/%d %H%M%S', errors='coerce') # 提取'運輸業者'包含鐵路、捷運、微笑單車、渡輪等字樣的data excluded_transport = ['鐵路', '捷運', '輕軌','微笑單車', '渡輪','輕軌', '府城'] dataframe = dataframe[dataframe['運輸業者'].str.contains('|'.join(excluded_transport))] dataframe = dataframe[['交易日期時間', '內碼', '票卡序號', '運輸業者', '進上車站', '出下車站', '路線']] BUS_data_paths = r'C:\NCKU\2024 travel behavior analysis - MeNGO\TPASS_BUS.csv' BUS_data = pd.read_csv(BUS_data_paths) merged_data = pd.concat([BUS_data, dataframe], ignore_index=True) merged_data.to_csv('TPASS.csv', index=False, encoding='utf-8') end_time = time.time() print("execution_time: ", end_time - start_time, "秒") ``` ## 查看一個人的數據 ```python= import pandas as pd import glob file_path = r'C:\NCKU\2024 travel behavior analysis - MeNGO\TPASS.csv' dtype={'交易日期時間': str, '內碼': str, '票卡序號': int, '運輸業者': str, '進上車站': str, '出下車站': str, '路線': str, 'duration': str} dataframe = pd.read_csv(file_path,dtype=dtype) #剔除單車的資料 dataframe = dataframe[~dataframe['運輸業者'].str.contains('|'.join('單車'))] #選特定對象資料 #捷運範例****F23D3820****49502023 #捷運與客運****E21F9015****61314118 #捷運與單車****A23E5615****49814018 # #隨機選一個 # random_inner_code = dataframe['內碼'].sample(n=1).values[0] # filtered_data = dataframe[dataframe['內碼'] == random_inner_code] # 計算相同內碼,運輸業者種類 transport_counts = dataframe.groupby('內碼')['運輸業者'].nunique().sort_values(ascending=False) print(transport_counts) distribution = transport_counts.value_counts() print(distribution) #使用運輸業者種類最多的人 max_transport_count_inner_code = transport_counts.idxmax() filtered_data = dataframe[dataframe['內碼'] == max_transport_count_inner_code] filtered_data = filtered_data.sort_values(by=['票卡序號']).reset_index(drop=True) print(filtered_data.to_string()) ``` ## 含單車數據 * 內碼與運輸業者種類 ![image](https://hackmd.io/_uploads/rywxanCkR.png) * 使用運輸業者種類分布 ![image](https://hackmd.io/_uploads/SJKV63AyA.png) * 最多的人 (有503筆資料,以單車佔多數) ![image](https://hackmd.io/_uploads/BktuT2Cy0.png) ## 不含單車數據 * 內碼與運輸業者種類 ![image](https://hackmd.io/_uploads/BkQ6p2CJR.png) * 使用運輸業者種類分布 ![image](https://hackmd.io/_uploads/HymZAnAJR.png) * 最多的人 (有220筆資料,以客運佔多數) ![image](https://hackmd.io/_uploads/Bk1XC3RkC.png) ## 高雄客運資料merge ![image](https://hackmd.io/_uploads/HJqV1BIxR.png) 語音代碼會重複 => 使用路線代碼&路線名稱&招呼站名稱比對 ## TPASS 車站資料與 語音代碼、招呼站代碼不相符 ![image](https://hackmd.io/_uploads/BkMMFBLg0.png) ![image](https://hackmd.io/_uploads/S1FVYr8lA.png) # MaaS ## 招呼站代碼相同就是同位置 > 1030個站 ![image](https://hackmd.io/_uploads/S1RqcsRlA.png) ![image](https://hackmd.io/_uploads/ByTMe63bC.png) ![image](https://hackmd.io/_uploads/B1QKl6nZC.png) ## merge回MaaS的票卡od資料 ![image](https://hackmd.io/_uploads/ryM4fanWC.png)