From dc23f9b921902f85a7781d62233072fbb580585d Mon Sep 17 00:00:00 2001 From: V Date: Fri, 21 Jun 2024 21:33:25 +0000 Subject: [PATCH 1/3] Adds ntd ridership numbers and impact analysis --- holiday_service_research/funcs_vars.py | 6 +- .../holiday_research.ipynb | 1659 ++++++++++++++++- 2 files changed, 1637 insertions(+), 28 deletions(-) diff --git a/holiday_service_research/funcs_vars.py b/holiday_service_research/funcs_vars.py index 446f3ad02..f38a72ba8 100644 --- a/holiday_service_research/funcs_vars.py +++ b/holiday_service_research/funcs_vars.py @@ -140,7 +140,11 @@ def plot_confusion_matrices(df, y_true, y_pred, title): # return cm, df_cm excel_col_order = ['Name', 'Notes', 'gtfs_dataset_name', -'Total VOMS (NTD) (from Provider)', 'Customer Facing',"name", +'Total VOMS (NTD) (from Provider)', +'sum_unlinked_passenger_trips_upt', +'ntd_id_2022', +'Customer Facing', +"name", "Reference Saturday", "Reference Sunday", "Reference Weekday", diff --git a/holiday_service_research/holiday_research.ipynb b/holiday_service_research/holiday_research.ipynb index 2b9431d00..7649faee4 100644 --- a/holiday_service_research/holiday_research.ipynb +++ b/holiday_service_research/holiday_research.ipynb @@ -18,7 +18,7 @@ "- Prescribe a gtfs service level by fraction\n", "- Create confusion matrices\n", "- Make another plot\n", - "\n", + "- Added ridership, made ridership / impact plots\n", "TODOs:\n", "- Instead of query by name, make a join between int_gtfs_quality__daily_assessment_candidate_entities and fct_scheduled_trips by the appropriate method. This will prevent issues where the gtfs schedule name changes will affect the joins. This should help ensure the analysis is perfectly replicable in the future.\n", "- Refactor so there aren't multiple lists of text columns\n", @@ -77,7 +77,21 @@ "execution_count": 3, "id": "edd2b5cc-e11b-4434-bee2-381fb3a91bc1", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Index(['id', 'Name', 'Notes', 'Provider', 'website', 'Service Type', 'Mode',\n", + " 'Rider Requirements', 'Currently Operating', 'Funding Sources',\n", + " ...\n", + " 'Product: Payments', 'Deprecated Date', 'Next Steps',\n", + " 'New Contact Info (from USDOT)', 'Context from Juliet', 'Season Start',\n", + " 'Season End', 'organizations 2', 'eligibility programs', 'Start Date'],\n", + " dtype='object', length=123)\n" + ] + } + ], "source": [ "# Trying to stay consistent with \n", "# https://github.com/cal-itp/data-infra/blob/main/airflow/plugins/operators/airtable_to_gcs.py\n", @@ -102,7 +116,10 @@ "services_df = all_rows_as_df(CALIFORNIA_TRANSIT_ID, SERVICES_ID)\n", "gtfs_services = all_rows_as_df(CALIFORNIA_TRANSIT_ID, GTFS_SERVICES)\n", "\n", + "services_df = services_df.rename(columns={\"ntd_id_2022 (from Provider)\":\"ntd_id_2022\"})\n", "services_df['Total VOMS (NTD) (from Provider)'] = services_df['Total VOMS (NTD) (from Provider)'].apply(takeout_list)\n", + "print(services_df.columns)\n", + "services_df[\"ntd_id_2022\"] = services_df[\"ntd_id_2022\"].apply(takeout_list)\n", "services_df = services_df.loc[~services_df['Holiday Schedule – Veterans Day'].isnull(),]\n", "services_df = services_df.loc[services_df['Public Currently Operating Fixed Route'] == 'Yes',]\n", "\n", @@ -169,10 +186,7 @@ "trips = trips.replace({\"service_date\":date_to_name})\n", "\n", "#https://hackersandslackers.com/reshaping-pandas-dataframes/\n", - "trips_pivoted = pd.pivot_table(trips, index='name',columns='service_date',fill_value = 0,values='total_trips')\n", - "\n", - "df_with_data = pd.merge(services_plus_service_names[['Name','Notes','gtfs_dataset_name','Total VOMS (NTD) (from Provider)', 'Customer Facing']+holiday_columns], \n", - " trips_pivoted.reset_index(),how='left', left_on='gtfs_dataset_name', right_on='name',indicator=True)" + "trips_pivoted = pd.pivot_table(trips, index='name',columns='service_date',fill_value = 0,values='total_trips')" ] }, { @@ -185,20 +199,21 @@ "name": "stdout", "output_type": "stream", "text": [ - "(202, 29)\n", - "(188, 29)\n", - "(161, 29)\n", + "(202, 30)\n", + "(188, 30)\n", + "(161, 30)\n", "39 San Juan Capistrano Free Weekend Trolley\n", "51 Amtrak San Joaquins\n", "96 Glendora Shuttles\n", "144 Blossom Express\n", "Name: Name, dtype: object\n", - "(157, 28)\n" + "(157, 29)\n" ] } ], "source": [ - "df_with_data = pd.merge(services_plus_service_names[['Name','Notes','gtfs_dataset_name','Total VOMS (NTD) (from Provider)', 'Customer Facing']+holiday_columns], trips_pivoted.reset_index(),how='left', left_on='gtfs_dataset_name', right_on='name',indicator=True)\n", + "df_with_data = pd.merge(services_plus_service_names[['Name','Notes','gtfs_dataset_name','Total VOMS (NTD) (from Provider)', 'ntd_id_2022', 'Customer Facing']+holiday_columns], \n", + " trips_pivoted.reset_index(),how='left', left_on='gtfs_dataset_name', right_on='name',indicator=True)\n", "\n", "print(df_with_data.shape)\n", "\n", @@ -230,6 +245,177 @@ { "cell_type": "code", "execution_count": 6, + "id": "3ddb82ac-0685-4ee6-a46b-8d58e1408d28", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "137\n" + ] + } + ], + "source": [ + "print(len(set(df_with_data['ntd_id_2022'].dropna().tolist())))\n", + "ntd_ids = list(set(df_with_data['ntd_id_2022'].dropna()))\n", + "ntd_ids_for_query = ','.join(map(\"'{0}'\".format, ntd_ids))" + ] + }, + { + "cell_type": "markdown", + "id": "435d84c9-f723-42ff-b964-63f5e4652e11", + "metadata": {}, + "source": [ + "This query sums by all these different modes:\n", + " \"mode\": \"MG\" • Monorail/Automated guideway transit (MG)\n", + " \"mode\": \"YR\" • Hybrid rail (YR);\n", + " \"mode\": \"HR\" • Heavy rail (HR);\n", + " \"mode\": \"MB\" • Bus (MB)\n", + " \"mode\": \"DR\" • Demand Response (DR)\n", + " \"mode\": \"CB\" • Commuter bus (CB)\n", + " \"mode\": \"LR\" • Light rail (LR);\n", + " \"mode\": \"RB\" • Bus Rapid Transit (RB); and\n", + " \"mode\": \"SR\" • Streetcar (SR)\n", + " \"mode\": \"TB\" • Trolleybus (TB)\n", + " \"mode\": \"CC\" • Cable car (CC);\n", + " \"mode\": \"FB\" • Ferryboats (FB)\n", + " \"mode\": \"CR\" • Commuter rail (CR);\n", + " \"mode\": \"VP\" Vanpool (VP)\n", + " \n" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "f7aee78a-3111-45e4-a49c-bab62a5c2a83", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
yearntd_id_2022agency_namereporter_typetime_periodsum_unlinked_passenger_trips_upt
0202290003San Francisco Bay Area Rapid Transit DistrictFull ReporterAnnual Total38224072.0
1202290004Golden Empire Transit DistrictFull ReporterAnnual Total3201046.0
2202290006Santa Cruz Metropolitan Transit DistrictFull ReporterAnnual Total2837891.0
3202290008City of Santa MonicaFull ReporterAnnual Total6333923.0
4202290009San Mateo County Transit DistrictFull ReporterAnnual Total7128074.0
\n", + "
" + ], + "text/plain": [ + " year ntd_id_2022 agency_name \\\n", + "0 2022 90003 San Francisco Bay Area Rapid Transit District \n", + "1 2022 90004 Golden Empire Transit District \n", + "2 2022 90006 Santa Cruz Metropolitan Transit District \n", + "3 2022 90008 City of Santa Monica \n", + "4 2022 90009 San Mateo County Transit District \n", + "\n", + " reporter_type time_period sum_unlinked_passenger_trips_upt \n", + "0 Full Reporter Annual Total 38224072.0 \n", + "1 Full Reporter Annual Total 3201046.0 \n", + "2 Full Reporter Annual Total 2837891.0 \n", + "3 Full Reporter Annual Total 6333923.0 \n", + "4 Full Reporter Annual Total 7128074.0 " + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "upt = query_sql(f\"\"\"\n", + "SELECT year, ntd_id as ntd_id_2022, agency_name, reporter_type, time_period, sum(unlinked_passenger_trips__upt_) as sum_unlinked_passenger_trips_upt \n", + "FROM `cal-itp-data-infra.mart_ntd.dim_annual_ntd_agency_service` \n", + "where ntd_id in ({ntd_ids_for_query})\n", + "and time_period = 'Annual Total'\n", + "and year = 2022\n", + "group by 1,2,3,4,5;\n", + "\"\"\", as_df=True)\n", + "upt.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "b5128d68-b340-4195-8faa-4c5e58cb38e7", + "metadata": {}, + "outputs": [], + "source": [ + "df_with_data = pd.merge(df_with_data, upt[['ntd_id_2022','agency_name','sum_unlinked_passenger_trips_upt']],how='left')" + ] + }, + { + "cell_type": "code", + "execution_count": 9, "id": "9935a28f-06ef-4bf0-9050-c2df8e107aeb", "metadata": {}, "outputs": [ @@ -259,7 +445,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 10, "id": "284f56c4-eb92-4789-b038-7bbe5835c00c", "metadata": {}, "outputs": [ @@ -286,7 +472,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 11, "id": "5002ca16-b060-4e52-83e7-6420927194a5", "metadata": {}, "outputs": [ @@ -313,7 +499,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 12, "id": "99fd4fa0-cee3-4da3-a628-7850e2968154", "metadata": {}, "outputs": [ @@ -340,7 +526,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 13, "id": "0bbe6eb9-654b-46ac-9817-dc5a91f8081f", "metadata": {}, "outputs": [], @@ -362,7 +548,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 14, "id": "59a2de39-e4fa-4e5a-8dad-03851e252a9f", "metadata": {}, "outputs": [], @@ -386,7 +572,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 15, "id": "baae1de1-fec0-4538-b3f3-e2a8aff54aa8", "metadata": { "tags": [] @@ -399,7 +585,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 16, "id": "d09bf955-6baf-4737-b353-12ee0dfa2b43", "metadata": {}, "outputs": [], @@ -409,7 +595,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 17, "id": "05e69050-41bf-40bc-b2f3-aee62ddaa81a", "metadata": {}, "outputs": [ @@ -513,12 +699,12 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 18, "id": "62a6f061-b7d5-4dc9-8e5f-279a01d39252", "metadata": {}, "outputs": [], "source": [ - "df = df_without_values\n", + "df = df_without_values.copy(deep=True)\n", "t = []\n", "names = []\n", "for day in holidays_plus_ref:\n", @@ -534,7 +720,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 19, "id": "15d04ee6-b483-4f1f-a519-e10c6177fdbd", "metadata": {}, "outputs": [ @@ -784,7 +970,7 @@ "MLK Day 68 " ] }, - "execution_count": 16, + "execution_count": 19, "metadata": {}, "output_type": "execute_result" } @@ -805,7 +991,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 20, "id": "49256d75-38fa-42ec-99f2-9380c535b243", "metadata": {}, "outputs": [], @@ -821,17 +1007,16 @@ " +plot_df['GTFS Reduced service, Regular service on Website'])\n", "\n", "label_order = ['GTFS greater than Website','GTFS matches Website', 'GTFS less than Website']\n", - "plot_df[label_order].sum(axis=1)\n", "percentages_df = plot_df[label_order].div(\n", " plot_df[label_order].sum(axis=1),axis=0).round(2)*100\n", - "percentages_df\n", + "# percentages_df\n", "\n", "percentages_df.round(2).to_csv(\"percentages.csv\")" ] }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 21, "id": "061a55c2-2ef7-4246-a5b7-817fa1b995a8", "metadata": {}, "outputs": [ @@ -856,6 +1041,1426 @@ "plt.title(title)\n", "plt.savefig(f\"plots/comparison.png\")" ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "14eec3fc-183b-41b0-bf19-458c028c0599", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
NameNotesgtfs_dataset_nameTotal VOMS (NTD) (from Provider)ntd_id_2022Customer FacingHoliday Schedule – Thanksgiving DayHoliday Schedule – Christmas DayHoliday Schedule – New Year's DayHoliday Schedule – MLK Day...sum_unlinked_passenger_trips_uptscore_text - Veterans Day (Observed)score_text - Thanksgiving Dayscore_text - Day After Thanksgivingscore_text - Christmas Dayscore_text - New Year's Dayscore_text - MLK Dayscore_text - Veterans Dayscore_text - Christmas Evescore_text - New Year's Eve
35Gold Coast TransitGold Coast Transit District provides public tr...Gold Coast Schedule72.090035NaNNo serviceNo serviceNo serviceRegular service...2337201.0Regular serviceNo serviceRegular serviceNo serviceNo serviceNo serviceRegular serviceRegular serviceRegular service
36Gold Coast TransitGold Coast Transit District provides public tr...VCTC GMV Schedule72.090035TrueNo serviceNo serviceNo serviceRegular service...2337201.0Regular serviceReduced serviceRegular serviceReduced serviceReduced serviceRegular serviceRegular serviceRegular serviceRegular service
\n", + "

2 rows × 28 columns

\n", + "
" + ], + "text/plain": [ + " Name Notes \\\n", + "35 Gold Coast Transit Gold Coast Transit District provides public tr... \n", + "36 Gold Coast Transit Gold Coast Transit District provides public tr... \n", + "\n", + " gtfs_dataset_name Total VOMS (NTD) (from Provider) ntd_id_2022 \\\n", + "35 Gold Coast Schedule 72.0 90035 \n", + "36 VCTC GMV Schedule 72.0 90035 \n", + "\n", + " Customer Facing Holiday Schedule – Thanksgiving Day \\\n", + "35 NaN No service \n", + "36 True No service \n", + "\n", + " Holiday Schedule – Christmas Day Holiday Schedule – New Year's Day \\\n", + "35 No service No service \n", + "36 No service No service \n", + "\n", + " Holiday Schedule – MLK Day ... sum_unlinked_passenger_trips_upt \\\n", + "35 Regular service ... 2337201.0 \n", + "36 Regular service ... 2337201.0 \n", + "\n", + " score_text - Veterans Day (Observed) score_text - Thanksgiving Day \\\n", + "35 Regular service No service \n", + "36 Regular service Reduced service \n", + "\n", + " score_text - Day After Thanksgiving score_text - Christmas Day \\\n", + "35 Regular service No service \n", + "36 Regular service Reduced service \n", + "\n", + " score_text - New Year's Day score_text - MLK Day score_text - Veterans Day \\\n", + "35 No service No service Regular service \n", + "36 Reduced service Regular service Regular service \n", + "\n", + " score_text - Christmas Eve score_text - New Year's Eve \n", + "35 Regular service Regular service \n", + "36 Regular service Regular service \n", + "\n", + "[2 rows x 28 columns]" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df_without_values.loc[df_without_values[\"ntd_id_2022\"]=='90035',]" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "ff410a33-8c52-4c49-904f-c3d13c314163", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
NameNotesgtfs_dataset_nameTotal VOMS (NTD) (from Provider)ntd_id_2022Customer FacingHoliday Schedule – Thanksgiving DayHoliday Schedule – Christmas DayHoliday Schedule – New Year's DayHoliday Schedule – MLK Day...sum_unlinked_passenger_trips_uptscore_text - Veterans Day (Observed)score_text - Thanksgiving Dayscore_text - Day After Thanksgivingscore_text - Christmas Dayscore_text - New Year's Dayscore_text - MLK Dayscore_text - Veterans Dayscore_text - Christmas Evescore_text - New Year's Eve
49Golden Gate TransitThe Golden Gate Bridge, Highway and Transporta...Bay Area 511 Golden Gate Transit Schedule154.090016NaNReduced serviceRegular serviceReduced serviceRegular service...1745434.0Regular serviceReduced serviceReduced serviceReduced serviceReduced serviceRegular serviceRegular serviceRegular serviceRegular service
139Golden Gate FerriesGolden Gate Ferry operates from four (4) locat...Bay Area 511 Golden Gate Ferry Schedule154.090016NaNNo serviceNo serviceNo serviceReduced service...1745434.0Regular serviceNo serviceReduced serviceNo serviceNo serviceRegular serviceRegular serviceRegular serviceRegular service
\n", + "

2 rows × 28 columns

\n", + "
" + ], + "text/plain": [ + " Name Notes \\\n", + "49 Golden Gate Transit The Golden Gate Bridge, Highway and Transporta... \n", + "139 Golden Gate Ferries Golden Gate Ferry operates from four (4) locat... \n", + "\n", + " gtfs_dataset_name \\\n", + "49 Bay Area 511 Golden Gate Transit Schedule \n", + "139 Bay Area 511 Golden Gate Ferry Schedule \n", + "\n", + " Total VOMS (NTD) (from Provider) ntd_id_2022 Customer Facing \\\n", + "49 154.0 90016 NaN \n", + "139 154.0 90016 NaN \n", + "\n", + " Holiday Schedule – Thanksgiving Day Holiday Schedule – Christmas Day \\\n", + "49 Reduced service Regular service \n", + "139 No service No service \n", + "\n", + " Holiday Schedule – New Year's Day Holiday Schedule – MLK Day ... \\\n", + "49 Reduced service Regular service ... \n", + "139 No service Reduced service ... \n", + "\n", + " sum_unlinked_passenger_trips_upt score_text - Veterans Day (Observed) \\\n", + "49 1745434.0 Regular service \n", + "139 1745434.0 Regular service \n", + "\n", + " score_text - Thanksgiving Day score_text - Day After Thanksgiving \\\n", + "49 Reduced service Reduced service \n", + "139 No service Reduced service \n", + "\n", + " score_text - Christmas Day score_text - New Year's Day \\\n", + "49 Reduced service Reduced service \n", + "139 No service No service \n", + "\n", + " score_text - MLK Day score_text - Veterans Day \\\n", + "49 Regular service Regular service \n", + "139 Regular service Regular service \n", + "\n", + " score_text - Christmas Eve score_text - New Year's Eve \n", + "49 Regular service Regular service \n", + "139 Regular service Regular service \n", + "\n", + "[2 rows x 28 columns]" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df_without_values.loc[df_without_values[\"ntd_id_2022\"]=='90016',]" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "55481813-90e6-42db-b987-faea56b857c6", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
NameNotesgtfs_dataset_nameTotal VOMS (NTD) (from Provider)ntd_id_2022Customer FacingHoliday Schedule – Thanksgiving DayHoliday Schedule – Christmas DayHoliday Schedule – New Year's DayHoliday Schedule – MLK Day...sum_unlinked_passenger_trips_uptscore_text - Veterans Day (Observed)score_text - Thanksgiving Dayscore_text - Day After Thanksgivingscore_text - Christmas Dayscore_text - New Year's Dayscore_text - MLK Dayscore_text - Veterans Dayscore_text - Christmas Evescore_text - New Year's Eve
51LA Metro RailMetro rail refers to the A (Blue), B (Red), C ...LA Metro Rail Schedule3458.090154TrueReduced serviceReduced serviceReduced serviceRegular service...254688124.0Regular serviceReduced serviceRegular serviceReduced serviceRegular serviceRegular serviceRegular serviceRegular serviceRegular service
65LA Metro BusNaNLA Metro Bus Schedule3458.090154TrueReduced serviceReduced serviceReduced serviceRegular service...254688124.0Regular serviceReduced serviceRegular serviceReduced serviceReduced serviceRegular serviceRegular serviceRegular serviceRegular service
\n", + "

2 rows × 28 columns

\n", + "
" + ], + "text/plain": [ + " Name Notes \\\n", + "51 LA Metro Rail Metro rail refers to the A (Blue), B (Red), C ... \n", + "65 LA Metro Bus NaN \n", + "\n", + " gtfs_dataset_name Total VOMS (NTD) (from Provider) ntd_id_2022 \\\n", + "51 LA Metro Rail Schedule 3458.0 90154 \n", + "65 LA Metro Bus Schedule 3458.0 90154 \n", + "\n", + " Customer Facing Holiday Schedule – Thanksgiving Day \\\n", + "51 True Reduced service \n", + "65 True Reduced service \n", + "\n", + " Holiday Schedule – Christmas Day Holiday Schedule – New Year's Day \\\n", + "51 Reduced service Reduced service \n", + "65 Reduced service Reduced service \n", + "\n", + " Holiday Schedule – MLK Day ... sum_unlinked_passenger_trips_upt \\\n", + "51 Regular service ... 254688124.0 \n", + "65 Regular service ... 254688124.0 \n", + "\n", + " score_text - Veterans Day (Observed) score_text - Thanksgiving Day \\\n", + "51 Regular service Reduced service \n", + "65 Regular service Reduced service \n", + "\n", + " score_text - Day After Thanksgiving score_text - Christmas Day \\\n", + "51 Regular service Reduced service \n", + "65 Regular service Reduced service \n", + "\n", + " score_text - New Year's Day score_text - MLK Day score_text - Veterans Day \\\n", + "51 Regular service Regular service Regular service \n", + "65 Reduced service Regular service Regular service \n", + "\n", + " score_text - Christmas Eve score_text - New Year's Eve \n", + "51 Regular service Regular service \n", + "65 Regular service Regular service \n", + "\n", + "[2 rows x 28 columns]" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df_without_values.loc[df_without_values[\"ntd_id_2022\"]=='90154',]" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "8959cabe-ef6a-4d5e-beb3-f088951b8811", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
NameNotesgtfs_dataset_nameTotal VOMS (NTD) (from Provider)ntd_id_2022Customer FacingHoliday Schedule – Thanksgiving DayHoliday Schedule – Christmas DayHoliday Schedule – New Year's DayHoliday Schedule – MLK Day...sum_unlinked_passenger_trips_uptscore_text - Veterans Day (Observed)score_text - Thanksgiving Dayscore_text - Day After Thanksgivingscore_text - Christmas Dayscore_text - New Year's Dayscore_text - MLK Dayscore_text - Veterans Dayscore_text - Christmas Evescore_text - New Year's Eve
51LA Metro RailMetro rail refers to the A (Blue), B (Red), C ...LA Metro Rail Schedule3458.090154TrueReduced serviceReduced serviceReduced serviceRegular service...254688124.0Regular serviceReduced serviceRegular serviceReduced serviceRegular serviceRegular serviceRegular serviceRegular serviceRegular service
65LA Metro BusNaNLA Metro Bus Schedule3458.090154TrueReduced serviceReduced serviceReduced serviceRegular service...254688124.0Regular serviceReduced serviceRegular serviceReduced serviceReduced serviceRegular serviceRegular serviceRegular serviceRegular service
\n", + "

2 rows × 28 columns

\n", + "
" + ], + "text/plain": [ + " Name Notes \\\n", + "51 LA Metro Rail Metro rail refers to the A (Blue), B (Red), C ... \n", + "65 LA Metro Bus NaN \n", + "\n", + " gtfs_dataset_name Total VOMS (NTD) (from Provider) ntd_id_2022 \\\n", + "51 LA Metro Rail Schedule 3458.0 90154 \n", + "65 LA Metro Bus Schedule 3458.0 90154 \n", + "\n", + " Customer Facing Holiday Schedule – Thanksgiving Day \\\n", + "51 True Reduced service \n", + "65 True Reduced service \n", + "\n", + " Holiday Schedule – Christmas Day Holiday Schedule – New Year's Day \\\n", + "51 Reduced service Reduced service \n", + "65 Reduced service Reduced service \n", + "\n", + " Holiday Schedule – MLK Day ... sum_unlinked_passenger_trips_upt \\\n", + "51 Regular service ... 254688124.0 \n", + "65 Regular service ... 254688124.0 \n", + "\n", + " score_text - Veterans Day (Observed) score_text - Thanksgiving Day \\\n", + "51 Regular service Reduced service \n", + "65 Regular service Reduced service \n", + "\n", + " score_text - Day After Thanksgiving score_text - Christmas Day \\\n", + "51 Regular service Reduced service \n", + "65 Regular service Reduced service \n", + "\n", + " score_text - New Year's Day score_text - MLK Day score_text - Veterans Day \\\n", + "51 Regular service Regular service Regular service \n", + "65 Reduced service Regular service Regular service \n", + "\n", + " score_text - Christmas Eve score_text - New Year's Eve \n", + "51 Regular service Regular service \n", + "65 Regular service Regular service \n", + "\n", + "[2 rows x 28 columns]" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df_without_values.loc[df_without_values[\"ntd_id_2022\"]=='90154',]" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "46cdd557-d8d3-4716-8976-5edaf31766c9", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "254688124.0\n" + ] + } + ], + "source": [ + "df = df_without_values.copy(deep=True)\n", + "\n", + "# Weekday bus: 750598 \n", + "# Weekday Rail: 205,320\n", + "# https://www.metro.net/about/l-a-metros-weekday-ridership-up-14-percent-year-over-year-in-march/\n", + "#What is the ridership / trips split between LA Metro Bus / LA Metro Rail? \n", + "\n", + "#La Metro bus got dropped - LA Rail actually got rated as Greater than Website for NY Day. Instead maybe we should distribute trips / ridership between the two agencies.\n", + "\n", + "rail_percent = 205320/(205320+750598)\n", + "bus_percent = 750598/(205320+750598)\n", + "rail_percent+bus_percent\n", + "\n", + "# Adjust LA Metro rail so it has a different ntd_id than la metro bus.\n", + "df.loc[df[\"gtfs_dataset_name\"]=='LA Metro Rail Schedule','ntd_id_2022'] = '90154b'\n", + "\n", + "total_la_ridership = df.loc[df[\"gtfs_dataset_name\"]=='LA Metro Rail Schedule','sum_unlinked_passenger_trips_upt'].values[0]\n", + "print(total_la_ridership)\n", + "\n", + "df.loc[df[\"gtfs_dataset_name\"]=='LA Metro Rail Schedule','sum_unlinked_passenger_trips_upt'] = total_la_ridership*rail_percent\n", + "df.loc[df[\"gtfs_dataset_name\"]=='LA Metro Bus Schedule', 'sum_unlinked_passenger_trips_upt'] = total_la_ridership*bus_percent" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "73f187ba-f26c-4865-9c16-2e60df1bd448", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "51 5.470403e+07\n", + "Name: sum_unlinked_passenger_trips_upt, dtype: float64" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.loc[df[\"gtfs_dataset_name\"]=='LA Metro Rail Schedule','sum_unlinked_passenger_trips_upt']" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "e5dec9b9-14a5-4bbd-84ae-b2def6af06b7", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "65 1.999841e+08\n", + "Name: sum_unlinked_passenger_trips_upt, dtype: float64" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.loc[df[\"gtfs_dataset_name\"]=='LA Metro Bus Schedule', 'sum_unlinked_passenger_trips_upt']" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "b002c822-1d91-4a3b-bbe4-140e5ae6067b", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
NameNotesgtfs_dataset_nameTotal VOMS (NTD) (from Provider)ntd_id_2022Customer FacingHoliday Schedule – Thanksgiving DayHoliday Schedule – Christmas DayHoliday Schedule – New Year's DayHoliday Schedule – MLK Day...sum_unlinked_passenger_trips_uptscore_text - Veterans Day (Observed)score_text - Thanksgiving Dayscore_text - Day After Thanksgivingscore_text - Christmas Dayscore_text - New Year's Dayscore_text - MLK Dayscore_text - Veterans Dayscore_text - Christmas Evescore_text - New Year's Eve
51LA Metro RailMetro rail refers to the A (Blue), B (Red), C ...LA Metro Rail Schedule3458.090154bTrueReduced serviceReduced serviceReduced serviceRegular service...5.470403e+07Regular serviceReduced serviceRegular serviceReduced serviceRegular serviceRegular serviceRegular serviceRegular serviceRegular service
\n", + "

1 rows × 28 columns

\n", + "
" + ], + "text/plain": [ + " Name Notes \\\n", + "51 LA Metro Rail Metro rail refers to the A (Blue), B (Red), C ... \n", + "\n", + " gtfs_dataset_name Total VOMS (NTD) (from Provider) ntd_id_2022 \\\n", + "51 LA Metro Rail Schedule 3458.0 90154b \n", + "\n", + " Customer Facing Holiday Schedule – Thanksgiving Day \\\n", + "51 True Reduced service \n", + "\n", + " Holiday Schedule – Christmas Day Holiday Schedule – New Year's Day \\\n", + "51 Reduced service Reduced service \n", + "\n", + " Holiday Schedule – MLK Day ... sum_unlinked_passenger_trips_upt \\\n", + "51 Regular service ... 5.470403e+07 \n", + "\n", + " score_text - Veterans Day (Observed) score_text - Thanksgiving Day \\\n", + "51 Regular service Reduced service \n", + "\n", + " score_text - Day After Thanksgiving score_text - Christmas Day \\\n", + "51 Regular service Reduced service \n", + "\n", + " score_text - New Year's Day score_text - MLK Day score_text - Veterans Day \\\n", + "51 Regular service Regular service Regular service \n", + "\n", + " score_text - Christmas Eve score_text - New Year's Eve \n", + "51 Regular service Regular service \n", + "\n", + "[1 rows x 28 columns]" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.loc[df[\"ntd_id_2022\"]=='90154b',]" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "8e21270e-62bb-4509-869a-e3fc8bf69d01", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
NameNotesgtfs_dataset_nameTotal VOMS (NTD) (from Provider)ntd_id_2022Customer FacingHoliday Schedule – Thanksgiving DayHoliday Schedule – Christmas DayHoliday Schedule – New Year's DayHoliday Schedule – MLK Day...sum_unlinked_passenger_trips_uptscore_text - Veterans Day (Observed)score_text - Thanksgiving Dayscore_text - Day After Thanksgivingscore_text - Christmas Dayscore_text - New Year's Dayscore_text - MLK Dayscore_text - Veterans Dayscore_text - Christmas Evescore_text - New Year's Eve
65LA Metro BusNaNLA Metro Bus Schedule3458.090154TrueReduced serviceReduced serviceReduced serviceRegular service...1.999841e+08Regular serviceReduced serviceRegular serviceReduced serviceReduced serviceRegular serviceRegular serviceRegular serviceRegular service
\n", + "

1 rows × 28 columns

\n", + "
" + ], + "text/plain": [ + " Name Notes gtfs_dataset_name \\\n", + "65 LA Metro Bus NaN LA Metro Bus Schedule \n", + "\n", + " Total VOMS (NTD) (from Provider) ntd_id_2022 Customer Facing \\\n", + "65 3458.0 90154 True \n", + "\n", + " Holiday Schedule – Thanksgiving Day Holiday Schedule – Christmas Day \\\n", + "65 Reduced service Reduced service \n", + "\n", + " Holiday Schedule – New Year's Day Holiday Schedule – MLK Day ... \\\n", + "65 Reduced service Regular service ... \n", + "\n", + " sum_unlinked_passenger_trips_upt score_text - Veterans Day (Observed) \\\n", + "65 1.999841e+08 Regular service \n", + "\n", + " score_text - Thanksgiving Day score_text - Day After Thanksgiving \\\n", + "65 Reduced service Regular service \n", + "\n", + " score_text - Christmas Day score_text - New Year's Day \\\n", + "65 Reduced service Reduced service \n", + "\n", + " score_text - MLK Day score_text - Veterans Day score_text - Christmas Eve \\\n", + "65 Regular service Regular service Regular service \n", + "\n", + " score_text - New Year's Eve \n", + "65 Regular service \n", + "\n", + "[1 rows x 28 columns]" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df = df.drop_duplicates(subset='ntd_id_2022', keep='first')\n", + "\n", + "df.loc[df[\"ntd_id_2022\"]=='90154',]" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "445f1750-c8f0-4b0c-bad1-a041ee45e33b", + "metadata": {}, + "outputs": [], + "source": [ + "#4 entries are 0\n", + "df = df.loc[~df['sum_unlinked_passenger_trips_upt'].isnull(),]" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "be11b4cd-f144-4b95-ad75-f73fd5dfad4f", + "metadata": {}, + "outputs": [], + "source": [ + "t = []\n", + "names = []\n", + "for day in holidays_plus_ref:\n", + " if day['name'] in saturday_holidays+sunday_holidays+weekday_holidays:\n", + " y_true = day['website_name']\n", + " y_pred = day['holiday_computed_text']\n", + " desired_order = ['No service', 'Reduced service', 'Regular service']\n", + " cm = confusion_matrix(y_true=df[y_true], y_pred=df[y_pred], labels=desired_order, sample_weight=df['sum_unlinked_passenger_trips_upt'])\n", + " t += [cm.flatten()]\n", + " names.append(day['name'])\n", + "j = np.concatenate((t),axis=0).reshape(9,9)" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "d55bc591-e918-4182-90d7-aff1299f6f0b", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
GTFS No service, No service on WebsiteGTFS Reduced service, No service on WebsiteGTFS Regular service, No service on WebsiteGTFS No service, Reduced service on WebsiteGTFS Reduced service, Reduced service on WebsiteGTFS Regular service, Reduced service on WebsiteGTFS No service, Regular service on WebsiteGTFS Reduced service, Regular service on WebsiteGTFS Regular service, Regular service on Website
Veterans Day (Observed)95411.00.0146659.04076921.09.027994e+061.030809e+063180111.0103077717.0565907829.0
Veterans Day2781524.00.01988723.0101922.02.838900e+051.270185e+086284691.02673900.0545410334.0
Thanksgiving Day42002495.05841551.017400109.0841343.04.696275e+081.508288e+081641.00.00.0
Day After Thanksgiving700856.00.0893723.04200340.03.733885e+071.248264e+08495818.01921643.0516165816.0
Christmas Eve9394235.00.00.07120464.00.000000e+001.456900e+0719273360.03507335.0632679059.0
Christmas Day46543497.04320693.014971578.018172316.05.864888e+081.429954e+071641.01745434.00.0
New Year's Eve9394235.00.00.07120464.00.000000e+003.394575e+0757442459.03507335.0575133208.0
New Year's Day35928405.04042576.04689215.021426808.04.843857e+086.900357e+071641.067044130.021404.0
MLK Day2312984.00.0508707.01422384.02.382115e+088.692951e+065041320.02065989.0428287598.0
\n", + "
" + ], + "text/plain": [ + " GTFS No service, No service on Website \\\n", + "Veterans Day (Observed) 95411.0 \n", + "Veterans Day 2781524.0 \n", + "Thanksgiving Day 42002495.0 \n", + "Day After Thanksgiving 700856.0 \n", + "Christmas Eve 9394235.0 \n", + "Christmas Day 46543497.0 \n", + "New Year's Eve 9394235.0 \n", + "New Year's Day 35928405.0 \n", + "MLK Day 2312984.0 \n", + "\n", + " GTFS Reduced service, No service on Website \\\n", + "Veterans Day (Observed) 0.0 \n", + "Veterans Day 0.0 \n", + "Thanksgiving Day 5841551.0 \n", + "Day After Thanksgiving 0.0 \n", + "Christmas Eve 0.0 \n", + "Christmas Day 4320693.0 \n", + "New Year's Eve 0.0 \n", + "New Year's Day 4042576.0 \n", + "MLK Day 0.0 \n", + "\n", + " GTFS Regular service, No service on Website \\\n", + "Veterans Day (Observed) 146659.0 \n", + "Veterans Day 1988723.0 \n", + "Thanksgiving Day 17400109.0 \n", + "Day After Thanksgiving 893723.0 \n", + "Christmas Eve 0.0 \n", + "Christmas Day 14971578.0 \n", + "New Year's Eve 0.0 \n", + "New Year's Day 4689215.0 \n", + "MLK Day 508707.0 \n", + "\n", + " GTFS No service, Reduced service on Website \\\n", + "Veterans Day (Observed) 4076921.0 \n", + "Veterans Day 101922.0 \n", + "Thanksgiving Day 841343.0 \n", + "Day After Thanksgiving 4200340.0 \n", + "Christmas Eve 7120464.0 \n", + "Christmas Day 18172316.0 \n", + "New Year's Eve 7120464.0 \n", + "New Year's Day 21426808.0 \n", + "MLK Day 1422384.0 \n", + "\n", + " GTFS Reduced service, Reduced service on Website \\\n", + "Veterans Day (Observed) 9.027994e+06 \n", + "Veterans Day 2.838900e+05 \n", + "Thanksgiving Day 4.696275e+08 \n", + "Day After Thanksgiving 3.733885e+07 \n", + "Christmas Eve 0.000000e+00 \n", + "Christmas Day 5.864888e+08 \n", + "New Year's Eve 0.000000e+00 \n", + "New Year's Day 4.843857e+08 \n", + "MLK Day 2.382115e+08 \n", + "\n", + " GTFS Regular service, Reduced service on Website \\\n", + "Veterans Day (Observed) 1.030809e+06 \n", + "Veterans Day 1.270185e+08 \n", + "Thanksgiving Day 1.508288e+08 \n", + "Day After Thanksgiving 1.248264e+08 \n", + "Christmas Eve 1.456900e+07 \n", + "Christmas Day 1.429954e+07 \n", + "New Year's Eve 3.394575e+07 \n", + "New Year's Day 6.900357e+07 \n", + "MLK Day 8.692951e+06 \n", + "\n", + " GTFS No service, Regular service on Website \\\n", + "Veterans Day (Observed) 3180111.0 \n", + "Veterans Day 6284691.0 \n", + "Thanksgiving Day 1641.0 \n", + "Day After Thanksgiving 495818.0 \n", + "Christmas Eve 19273360.0 \n", + "Christmas Day 1641.0 \n", + "New Year's Eve 57442459.0 \n", + "New Year's Day 1641.0 \n", + "MLK Day 5041320.0 \n", + "\n", + " GTFS Reduced service, Regular service on Website \\\n", + "Veterans Day (Observed) 103077717.0 \n", + "Veterans Day 2673900.0 \n", + "Thanksgiving Day 0.0 \n", + "Day After Thanksgiving 1921643.0 \n", + "Christmas Eve 3507335.0 \n", + "Christmas Day 1745434.0 \n", + "New Year's Eve 3507335.0 \n", + "New Year's Day 67044130.0 \n", + "MLK Day 2065989.0 \n", + "\n", + " GTFS Regular service, Regular service on Website \n", + "Veterans Day (Observed) 565907829.0 \n", + "Veterans Day 545410334.0 \n", + "Thanksgiving Day 0.0 \n", + "Day After Thanksgiving 516165816.0 \n", + "Christmas Eve 632679059.0 \n", + "Christmas Day 0.0 \n", + "New Year's Eve 575133208.0 \n", + "New Year's Day 21404.0 \n", + "MLK Day 428287598.0 " + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "column_order = [\"GTFS No service, No service on Website\",\n", + " \"GTFS Reduced service, No service on Website\",\n", + " \"GTFS Regular service, No service on Website\",\n", + "\"GTFS No service, Reduced service on Website\",\n", + " \"GTFS Reduced service, Reduced service on Website\",\n", + " \"GTFS Regular service, Reduced service on Website\", \n", + " \"GTFS No service, Regular service on Website\",\n", + " \"GTFS Reduced service, Regular service on Website\",\n", + " \"GTFS Regular service, Regular service on Website\"]\n", + "plot_df = pd.DataFrame(j, index=names, columns = column_order)\n", + "plot_df" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "a76a2d0d-7eae-46a3-bf9e-64702f3d6a2f", + "metadata": {}, + "outputs": [], + "source": [ + "plot_df['GTFS matches Website'] = (plot_df['GTFS No service, No service on Website'] \n", + " +plot_df['GTFS Reduced service, Reduced service on Website']\n", + " +plot_df['GTFS Regular service, Regular service on Website'])\n", + "plot_df['GTFS greater than Website'] = (plot_df['GTFS Reduced service, No service on Website'] \n", + " +plot_df['GTFS Regular service, No service on Website']\n", + " +plot_df['GTFS Regular service, Reduced service on Website'])\n", + "plot_df['GTFS less than Website'] = (plot_df['GTFS No service, Reduced service on Website'] \n", + " +plot_df['GTFS No service, Regular service on Website']\n", + " +plot_df['GTFS Reduced service, Regular service on Website'])\n", + "\n", + "label_order = ['GTFS greater than Website','GTFS matches Website', 'GTFS less than Website']\n", + "\n", + "impact_df = plot_df[label_order].div(365).round().astype(int)\n", + "\n", + "impact_df.to_csv(\"impact_trips.csv\")" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "391db97d-06b2-4274-a1e4-587cb27fac71", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
GTFS greater than WebsiteGTFS matches WebsiteGTFS less than Website
Veterans Day (Observed)32261575428302287
Veterans Day353444150267324823
Thanksgiving Day47690514017262310
Day After Thanksgiving344439151837118131
Christmas Eve39915175910581921
Christmas Day92032173433554574
New Year's Eve930021601445186494
New Year's Day2129741425577242391
MLK Day25210183236223369
\n", + "
" + ], + "text/plain": [ + " GTFS greater than Website GTFS matches Website \\\n", + "Veterans Day (Observed) 3226 1575428 \n", + "Veterans Day 353444 1502673 \n", + "Thanksgiving Day 476905 1401726 \n", + "Day After Thanksgiving 344439 1518371 \n", + "Christmas Eve 39915 1759105 \n", + "Christmas Day 92032 1734335 \n", + "New Year's Eve 93002 1601445 \n", + "New Year's Day 212974 1425577 \n", + "MLK Day 25210 1832362 \n", + "\n", + " GTFS less than Website \n", + "Veterans Day (Observed) 302287 \n", + "Veterans Day 24823 \n", + "Thanksgiving Day 2310 \n", + "Day After Thanksgiving 18131 \n", + "Christmas Eve 81921 \n", + "Christmas Day 54574 \n", + "New Year's Eve 186494 \n", + "New Year's Day 242391 \n", + "MLK Day 23369 " + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "impact_df" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "d10185bc-d049-48f8-8c23-1ae2e188ca32", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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8y5duoRq1arBw8MDwJtLjqekpODevXv8siAijTI2NsakSZPkjqFRr169wvz58+Hr68uihgocD0X9Hzc3N0RERODo0aPStODgYKSkpMDZ2Rn6+vrShakuXLgAIYTUMY+ISFM+//xzNGzYUO4YGvPbb7+hYsWKAKB2phhRQfkkD0X5+vrizz//xKNHj1ChQgXo6ekhLCwMQUFBmDhxIv777z+kpqaievXq2Lt3L0qVKoXLly9j1KhReP36NXR1dfHTTz/l+4qgREREpFmfZGFDREREysRDUURERKQYn1Tn4YyMDDx48AB6enofff0MIiIiKlxCCCQkJOCzzz774AVDP6nC5sGDB+zwS0REVExFR0dne4Hdt31ShU3mBamio6Ohr68vcxoiIiLKjfj4eJiamubqwpKfVGGTefhJX1+fhQ0REVExk5tuJOw8TERERIrBwoaIiIgU45M6FPUh6enpuRpEjai409HRUdRovkREmVjY/J/ExETExMR8cGRWIiVQqVQwMTFBuXLl5I5CRKRRLGzwpqUmJiYGZcqUQaVKlXiNG1I0IQSePn2KmJgY1K5dmy03RKQoLGwApKamQgiBSpUqoXTp0nLHISpwlSpVQmRkJFJTU1nYEJGisPPwW9hSQ58KvtaJSKlY2BAREZFi8FBUDmzX2xbIdq8Pup6r5VJTUzF37lxs2bIFWlpaKFmyJGrUqIEZM2bg119/xaVLlwAA//77L2rWrCkdQjt16hRsbW2hq6srTXNxccGqVatw4sQJTJ48Ga9fv0ZKSgqMjIywe/duVKlSpUD29UNmzJiByZMno1SpUvne1t69e2FsbIyGDRsCAAICAvDVV18hODg439vOzr1791CvXj28ePECJUuWBABYWFigSZMmWLduHQDg3Llz6NWrF6KionLczrp167B3717s3bs314/93XffwcrKCv3790dAQACSkpLQrl27/OwOEZFisLApogYPHozExEQEBgbCyMgIAHD06FGEhIRg1apV0nJmZmbYtm0bHBwc1NZ/d1paWhq6deuGo0ePwsnJCQAQEhKCsmXL5itnWloatLU/7mU0c+ZMfPXVV3kubLJ7zL1798LBwUEqbApajRo1UKVKFVy4cAFNmjRBdHQ09PT0cO7cOWkZf39/eHh4aPyxZ82aJf0/ICAAsbGxLGyIiP4PD0UVQaGhodizZw/W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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.rcParams.update({'font.size': 8})\n", + "title = 'Ridership Impact Comparison of GTFS / Holiday Service Levels'\n", + "colors = ['#2CA02C', '#1F77B4', '#FF7F0E']\n", + "# percentages_df.plot.bar(color=colors) \n", + "impact_df.plot.bar(color=colors) \n", + "\n", + "plt.xlabel('Holidays')\n", + "plt.ylabel('Expected Millions of Trips')\n", + "plt.title(title)\n", + "plt.savefig(f\"plots/impact_comparison.png\")" + ] } ], "metadata": { From cc5e7dbb5bf3efaff4f9eced9859cbdc2b9ceb24 Mon Sep 17 00:00:00 2001 From: V Date: Fri, 28 Jun 2024 17:12:32 +0000 Subject: [PATCH 2/3] Adds ridership impacts of website status --- holiday_service_research/funcs_vars.py | 1 + .../holiday_research.ipynb | 320 +++++++++++------- 2 files changed, 201 insertions(+), 120 deletions(-) diff --git a/holiday_service_research/funcs_vars.py b/holiday_service_research/funcs_vars.py index f38a72ba8..23bb8f59a 100644 --- a/holiday_service_research/funcs_vars.py +++ b/holiday_service_research/funcs_vars.py @@ -142,6 +142,7 @@ def plot_confusion_matrices(df, y_true, y_pred, title): excel_col_order = ['Name', 'Notes', 'gtfs_dataset_name', 'Total VOMS (NTD) (from Provider)', 'sum_unlinked_passenger_trips_upt', +'Holiday Website Status', 'ntd_id_2022', 'Customer Facing', "name", diff --git a/holiday_service_research/holiday_research.ipynb b/holiday_service_research/holiday_research.ipynb index 7649faee4..25c20396c 100644 --- a/holiday_service_research/holiday_research.ipynb +++ b/holiday_service_research/holiday_research.ipynb @@ -118,6 +118,7 @@ "\n", "services_df = services_df.rename(columns={\"ntd_id_2022 (from Provider)\":\"ntd_id_2022\"})\n", "services_df['Total VOMS (NTD) (from Provider)'] = services_df['Total VOMS (NTD) (from Provider)'].apply(takeout_list)\n", + "services_df['Holiday Website Status'] = services_df['Holiday Website Status'].apply(takeout_list)\n", "print(services_df.columns)\n", "services_df[\"ntd_id_2022\"] = services_df[\"ntd_id_2022\"].apply(takeout_list)\n", "services_df = services_df.loc[~services_df['Holiday Schedule – Veterans Day'].isnull(),]\n", @@ -199,20 +200,20 @@ "name": "stdout", "output_type": "stream", "text": [ - "(202, 30)\n", - "(188, 30)\n", - "(161, 30)\n", + "(202, 31)\n", + "(188, 31)\n", + "(161, 31)\n", "39 San Juan Capistrano Free Weekend Trolley\n", "51 Amtrak San Joaquins\n", "96 Glendora Shuttles\n", "144 Blossom Express\n", "Name: Name, dtype: object\n", - "(157, 29)\n" + "(157, 30)\n" ] } ], "source": [ - "df_with_data = pd.merge(services_plus_service_names[['Name','Notes','gtfs_dataset_name','Total VOMS (NTD) (from Provider)', 'ntd_id_2022', 'Customer Facing']+holiday_columns], \n", + "df_with_data = pd.merge(services_plus_service_names[['Name','Notes','gtfs_dataset_name','Total VOMS (NTD) (from Provider)', 'Holiday Website Status', 'ntd_id_2022', 'Customer Facing']+holiday_columns], \n", " trips_pivoted.reset_index(),how='left', left_on='gtfs_dataset_name', right_on='name',indicator=True)\n", "\n", "print(df_with_data.shape)\n", @@ -1042,11 +1043,21 @@ "plt.savefig(f\"plots/comparison.png\")" ] }, + { + "cell_type": "markdown", + "id": "9da353dc-53ff-4f00-b75b-f7dd562ac724", + "metadata": {}, + "source": [ + "Show the agencies with duplicate ntd ids" + ] + }, { "cell_type": "code", "execution_count": 22, "id": "14eec3fc-183b-41b0-bf19-458c028c0599", - "metadata": {}, + "metadata": { + "tags": [] + }, "outputs": [ { "data": { @@ -1073,12 +1084,12 @@ " Notes\n", " gtfs_dataset_name\n", " Total VOMS (NTD) (from Provider)\n", + " Holiday Website Status\n", " ntd_id_2022\n", " Customer Facing\n", " Holiday Schedule – Thanksgiving Day\n", " Holiday Schedule – Christmas Day\n", " Holiday Schedule – New Year's Day\n", - " Holiday Schedule – MLK Day\n", " ...\n", " sum_unlinked_passenger_trips_upt\n", " score_text - Veterans Day (Observed)\n", @@ -1099,12 +1110,12 @@ " Gold Coast Transit District provides public tr...\n", " Gold Coast Schedule\n", " 72.0\n", + " Current\n", " 90035\n", " NaN\n", " No service\n", " No service\n", " No service\n", - " Regular service\n", " ...\n", " 2337201.0\n", " Regular service\n", @@ -1123,12 +1134,12 @@ " Gold Coast Transit District provides public tr...\n", " VCTC GMV Schedule\n", " 72.0\n", + " Current\n", " 90035\n", " True\n", " No service\n", " No service\n", " No service\n", - " Regular service\n", " ...\n", " 2337201.0\n", " Regular service\n", @@ -1143,7 +1154,7 @@ " \n", " \n", "\n", - "

2 rows × 28 columns

\n", + "

2 rows × 29 columns

\n", "" ], "text/plain": [ @@ -1151,21 +1162,21 @@ "35 Gold Coast Transit Gold Coast Transit District provides public tr... \n", "36 Gold Coast Transit Gold Coast Transit District provides public tr... \n", "\n", - " gtfs_dataset_name Total VOMS (NTD) (from Provider) ntd_id_2022 \\\n", - "35 Gold Coast Schedule 72.0 90035 \n", - "36 VCTC GMV Schedule 72.0 90035 \n", + " gtfs_dataset_name Total VOMS (NTD) (from Provider) \\\n", + "35 Gold Coast Schedule 72.0 \n", + "36 VCTC GMV Schedule 72.0 \n", "\n", - " Customer Facing Holiday Schedule – Thanksgiving Day \\\n", - "35 NaN No service \n", - "36 True No service \n", + " Holiday Website Status ntd_id_2022 Customer Facing \\\n", + "35 Current 90035 NaN \n", + "36 Current 90035 True \n", "\n", - " Holiday Schedule – Christmas Day Holiday Schedule – New Year's Day \\\n", - "35 No service No service \n", - "36 No service No service \n", + " Holiday Schedule – Thanksgiving Day Holiday Schedule – Christmas Day \\\n", + "35 No service No service \n", + "36 No service No service \n", "\n", - " Holiday Schedule – MLK Day ... sum_unlinked_passenger_trips_upt \\\n", - "35 Regular service ... 2337201.0 \n", - "36 Regular service ... 2337201.0 \n", + " Holiday Schedule – New Year's Day ... sum_unlinked_passenger_trips_upt \\\n", + "35 No service ... 2337201.0 \n", + "36 No service ... 2337201.0 \n", "\n", " score_text - Veterans Day (Observed) score_text - Thanksgiving Day \\\n", "35 Regular service No service \n", @@ -1179,11 +1190,11 @@ "35 No service No service Regular service \n", "36 Reduced service Regular service Regular service \n", "\n", - " score_text - Christmas Eve score_text - New Year's Eve \n", - "35 Regular service Regular service \n", - "36 Regular service Regular service \n", + " score_text - Christmas Eve score_text - New Year's Eve \n", + "35 Regular service Regular service \n", + "36 Regular service Regular service \n", "\n", - "[2 rows x 28 columns]" + "[2 rows x 29 columns]" ] }, "execution_count": 22, @@ -1226,12 +1237,12 @@ " Notes\n", " gtfs_dataset_name\n", " Total VOMS (NTD) (from Provider)\n", + " Holiday Website Status\n", " ntd_id_2022\n", " Customer Facing\n", " Holiday Schedule – Thanksgiving Day\n", " Holiday Schedule – Christmas Day\n", " Holiday Schedule – New Year's Day\n", - " Holiday Schedule – MLK Day\n", " ...\n", " sum_unlinked_passenger_trips_upt\n", " score_text - Veterans Day (Observed)\n", @@ -1252,12 +1263,12 @@ " The Golden Gate Bridge, Highway and Transporta...\n", " Bay Area 511 Golden Gate Transit Schedule\n", " 154.0\n", + " Current\n", " 90016\n", " NaN\n", " Reduced service\n", " Regular service\n", " Reduced service\n", - " Regular service\n", " ...\n", " 1745434.0\n", " Regular service\n", @@ -1276,12 +1287,12 @@ " Golden Gate Ferry operates from four (4) locat...\n", " Bay Area 511 Golden Gate Ferry Schedule\n", " 154.0\n", + " Current\n", " 90016\n", " NaN\n", " No service\n", " No service\n", " No service\n", - " Reduced service\n", " ...\n", " 1745434.0\n", " Regular service\n", @@ -1296,7 +1307,7 @@ " \n", " \n", "\n", - "

2 rows × 28 columns

\n", + "

2 rows × 29 columns

\n", "" ], "text/plain": [ @@ -1308,17 +1319,17 @@ "49 Bay Area 511 Golden Gate Transit Schedule \n", "139 Bay Area 511 Golden Gate Ferry Schedule \n", "\n", - " Total VOMS (NTD) (from Provider) ntd_id_2022 Customer Facing \\\n", - "49 154.0 90016 NaN \n", - "139 154.0 90016 NaN \n", + " Total VOMS (NTD) (from Provider) Holiday Website Status ntd_id_2022 \\\n", + "49 154.0 Current 90016 \n", + "139 154.0 Current 90016 \n", "\n", - " Holiday Schedule – Thanksgiving Day Holiday Schedule – Christmas Day \\\n", - "49 Reduced service Regular service \n", - "139 No service No service \n", + " Customer Facing Holiday Schedule – Thanksgiving Day \\\n", + "49 NaN Reduced service \n", + "139 NaN No service \n", "\n", - " Holiday Schedule – New Year's Day Holiday Schedule – MLK Day ... \\\n", - "49 Reduced service Regular service ... \n", - "139 No service Reduced service ... \n", + " Holiday Schedule – Christmas Day Holiday Schedule – New Year's Day ... \\\n", + "49 Regular service Reduced service ... \n", + "139 No service No service ... \n", "\n", " sum_unlinked_passenger_trips_upt score_text - Veterans Day (Observed) \\\n", "49 1745434.0 Regular service \n", @@ -1332,15 +1343,15 @@ "49 Reduced service Reduced service \n", "139 No service No service \n", "\n", - " score_text - MLK Day score_text - Veterans Day \\\n", - "49 Regular service Regular service \n", - "139 Regular service Regular service \n", + " score_text - MLK Day score_text - Veterans Day score_text - Christmas Eve \\\n", + "49 Regular service Regular service Regular service \n", + "139 Regular service Regular service Regular service \n", "\n", - " score_text - Christmas Eve score_text - New Year's Eve \n", - "49 Regular service Regular service \n", - "139 Regular service Regular service \n", + " score_text - New Year's Eve \n", + "49 Regular service \n", + "139 Regular service \n", "\n", - "[2 rows x 28 columns]" + "[2 rows x 29 columns]" ] }, "execution_count": 23, @@ -1383,12 +1394,12 @@ " Notes\n", " gtfs_dataset_name\n", " Total VOMS (NTD) (from Provider)\n", + " Holiday Website Status\n", " ntd_id_2022\n", " Customer Facing\n", " Holiday Schedule – Thanksgiving Day\n", " Holiday Schedule – Christmas Day\n", " Holiday Schedule – New Year's Day\n", - " Holiday Schedule – MLK Day\n", " ...\n", " sum_unlinked_passenger_trips_upt\n", " score_text - Veterans Day (Observed)\n", @@ -1409,12 +1420,12 @@ " Metro rail refers to the A (Blue), B (Red), C ...\n", " LA Metro Rail Schedule\n", " 3458.0\n", + " Current\n", " 90154\n", " True\n", " Reduced service\n", " Reduced service\n", " Reduced service\n", - " Regular service\n", " ...\n", " 254688124.0\n", " Regular service\n", @@ -1433,12 +1444,12 @@ " NaN\n", " LA Metro Bus Schedule\n", " 3458.0\n", + " Current\n", " 90154\n", " True\n", " Reduced service\n", " Reduced service\n", " Reduced service\n", - " Regular service\n", " ...\n", " 254688124.0\n", " Regular service\n", @@ -1453,7 +1464,7 @@ " \n", " \n", "\n", - "

2 rows × 28 columns

\n", + "

2 rows × 29 columns

\n", "" ], "text/plain": [ @@ -1461,21 +1472,21 @@ "51 LA Metro Rail Metro rail refers to the A (Blue), B (Red), C ... \n", "65 LA Metro Bus NaN \n", "\n", - " gtfs_dataset_name Total VOMS (NTD) (from Provider) ntd_id_2022 \\\n", - "51 LA Metro Rail Schedule 3458.0 90154 \n", - "65 LA Metro Bus Schedule 3458.0 90154 \n", + " gtfs_dataset_name Total VOMS (NTD) (from Provider) \\\n", + "51 LA Metro Rail Schedule 3458.0 \n", + "65 LA Metro Bus Schedule 3458.0 \n", "\n", - " Customer Facing Holiday Schedule – Thanksgiving Day \\\n", - "51 True Reduced service \n", - "65 True Reduced service \n", + " Holiday Website Status ntd_id_2022 Customer Facing \\\n", + "51 Current 90154 True \n", + "65 Current 90154 True \n", "\n", - " Holiday Schedule – Christmas Day Holiday Schedule – New Year's Day \\\n", - "51 Reduced service Reduced service \n", - "65 Reduced service Reduced service \n", + " Holiday Schedule – Thanksgiving Day Holiday Schedule – Christmas Day \\\n", + "51 Reduced service Reduced service \n", + "65 Reduced service Reduced service \n", "\n", - " Holiday Schedule – MLK Day ... sum_unlinked_passenger_trips_upt \\\n", - "51 Regular service ... 254688124.0 \n", - "65 Regular service ... 254688124.0 \n", + " Holiday Schedule – New Year's Day ... sum_unlinked_passenger_trips_upt \\\n", + "51 Reduced service ... 254688124.0 \n", + "65 Reduced service ... 254688124.0 \n", "\n", " score_text - Veterans Day (Observed) score_text - Thanksgiving Day \\\n", "51 Regular service Reduced service \n", @@ -1489,11 +1500,11 @@ "51 Regular service Regular service Regular service \n", "65 Reduced service Regular service Regular service \n", "\n", - " score_text - Christmas Eve score_text - New Year's Eve \n", - "51 Regular service Regular service \n", - "65 Regular service Regular service \n", + " score_text - Christmas Eve score_text - New Year's Eve \n", + "51 Regular service Regular service \n", + "65 Regular service Regular service \n", "\n", - "[2 rows x 28 columns]" + "[2 rows x 29 columns]" ] }, "execution_count": 24, @@ -1536,12 +1547,12 @@ " Notes\n", " gtfs_dataset_name\n", " Total VOMS (NTD) (from Provider)\n", + " Holiday Website Status\n", " ntd_id_2022\n", " Customer Facing\n", " Holiday Schedule – Thanksgiving Day\n", " Holiday Schedule – Christmas Day\n", " Holiday Schedule – New Year's Day\n", - " Holiday Schedule – MLK Day\n", " ...\n", " sum_unlinked_passenger_trips_upt\n", " score_text - Veterans Day (Observed)\n", @@ -1562,12 +1573,12 @@ " Metro rail refers to the A (Blue), B (Red), C ...\n", " LA Metro Rail Schedule\n", " 3458.0\n", + " Current\n", " 90154\n", " True\n", " Reduced service\n", " Reduced service\n", " Reduced service\n", - " Regular service\n", " ...\n", " 254688124.0\n", " Regular service\n", @@ -1586,12 +1597,12 @@ " NaN\n", " LA Metro Bus Schedule\n", " 3458.0\n", + " Current\n", " 90154\n", " True\n", " Reduced service\n", " Reduced service\n", " Reduced service\n", - " Regular service\n", " ...\n", " 254688124.0\n", " Regular service\n", @@ -1606,7 +1617,7 @@ " \n", " \n", "\n", - "

2 rows × 28 columns

\n", + "

2 rows × 29 columns

\n", "" ], "text/plain": [ @@ -1614,21 +1625,21 @@ "51 LA Metro Rail Metro rail refers to the A (Blue), B (Red), C ... \n", "65 LA Metro Bus NaN \n", "\n", - " gtfs_dataset_name Total VOMS (NTD) (from Provider) ntd_id_2022 \\\n", - "51 LA Metro Rail Schedule 3458.0 90154 \n", - "65 LA Metro Bus Schedule 3458.0 90154 \n", + " gtfs_dataset_name Total VOMS (NTD) (from Provider) \\\n", + "51 LA Metro Rail Schedule 3458.0 \n", + "65 LA Metro Bus Schedule 3458.0 \n", "\n", - " Customer Facing Holiday Schedule – Thanksgiving Day \\\n", - "51 True Reduced service \n", - "65 True Reduced service \n", + " Holiday Website Status ntd_id_2022 Customer Facing \\\n", + "51 Current 90154 True \n", + "65 Current 90154 True \n", "\n", - " Holiday Schedule – Christmas Day Holiday Schedule – New Year's Day \\\n", - "51 Reduced service Reduced service \n", - "65 Reduced service Reduced service \n", + " Holiday Schedule – Thanksgiving Day Holiday Schedule – Christmas Day \\\n", + "51 Reduced service Reduced service \n", + "65 Reduced service Reduced service \n", "\n", - " Holiday Schedule – MLK Day ... sum_unlinked_passenger_trips_upt \\\n", - "51 Regular service ... 254688124.0 \n", - "65 Regular service ... 254688124.0 \n", + " Holiday Schedule – New Year's Day ... sum_unlinked_passenger_trips_upt \\\n", + "51 Reduced service ... 254688124.0 \n", + "65 Reduced service ... 254688124.0 \n", "\n", " score_text - Veterans Day (Observed) score_text - Thanksgiving Day \\\n", "51 Regular service Reduced service \n", @@ -1642,11 +1653,11 @@ "51 Regular service Regular service Regular service \n", "65 Reduced service Regular service Regular service \n", "\n", - " score_text - Christmas Eve score_text - New Year's Eve \n", - "51 Regular service Regular service \n", - "65 Regular service Regular service \n", + " score_text - Christmas Eve score_text - New Year's Eve \n", + "51 Regular service Regular service \n", + "65 Regular service Regular service \n", "\n", - "[2 rows x 28 columns]" + "[2 rows x 29 columns]" ] }, "execution_count": 25, @@ -1771,12 +1782,12 @@ " Notes\n", " gtfs_dataset_name\n", " Total VOMS (NTD) (from Provider)\n", + " Holiday Website Status\n", " ntd_id_2022\n", " Customer Facing\n", " Holiday Schedule – Thanksgiving Day\n", " Holiday Schedule – Christmas Day\n", " Holiday Schedule – New Year's Day\n", - " Holiday Schedule – MLK Day\n", " ...\n", " sum_unlinked_passenger_trips_upt\n", " score_text - Veterans Day (Observed)\n", @@ -1797,12 +1808,12 @@ " Metro rail refers to the A (Blue), B (Red), C ...\n", " LA Metro Rail Schedule\n", " 3458.0\n", + " Current\n", " 90154b\n", " True\n", " Reduced service\n", " Reduced service\n", " Reduced service\n", - " Regular service\n", " ...\n", " 5.470403e+07\n", " Regular service\n", @@ -1817,24 +1828,24 @@ " \n", " \n", "\n", - "

1 rows × 28 columns

\n", + "

1 rows × 29 columns

\n", "" ], "text/plain": [ " Name Notes \\\n", "51 LA Metro Rail Metro rail refers to the A (Blue), B (Red), C ... \n", "\n", - " gtfs_dataset_name Total VOMS (NTD) (from Provider) ntd_id_2022 \\\n", - "51 LA Metro Rail Schedule 3458.0 90154b \n", + " gtfs_dataset_name Total VOMS (NTD) (from Provider) \\\n", + "51 LA Metro Rail Schedule 3458.0 \n", "\n", - " Customer Facing Holiday Schedule – Thanksgiving Day \\\n", - "51 True Reduced service \n", + " Holiday Website Status ntd_id_2022 Customer Facing \\\n", + "51 Current 90154b True \n", "\n", - " Holiday Schedule – Christmas Day Holiday Schedule – New Year's Day \\\n", - "51 Reduced service Reduced service \n", + " Holiday Schedule – Thanksgiving Day Holiday Schedule – Christmas Day \\\n", + "51 Reduced service Reduced service \n", "\n", - " Holiday Schedule – MLK Day ... sum_unlinked_passenger_trips_upt \\\n", - "51 Regular service ... 5.470403e+07 \n", + " Holiday Schedule – New Year's Day ... sum_unlinked_passenger_trips_upt \\\n", + "51 Reduced service ... 5.470403e+07 \n", "\n", " score_text - Veterans Day (Observed) score_text - Thanksgiving Day \\\n", "51 Regular service Reduced service \n", @@ -1845,10 +1856,10 @@ " score_text - New Year's Day score_text - MLK Day score_text - Veterans Day \\\n", "51 Regular service Regular service Regular service \n", "\n", - " score_text - Christmas Eve score_text - New Year's Eve \n", - "51 Regular service Regular service \n", + " score_text - Christmas Eve score_text - New Year's Eve \n", + "51 Regular service Regular service \n", "\n", - "[1 rows x 28 columns]" + "[1 rows x 29 columns]" ] }, "execution_count": 29, @@ -1891,12 +1902,12 @@ " Notes\n", " gtfs_dataset_name\n", " Total VOMS (NTD) (from Provider)\n", + " Holiday Website Status\n", " ntd_id_2022\n", " Customer Facing\n", " Holiday Schedule – Thanksgiving Day\n", " Holiday Schedule – Christmas Day\n", " Holiday Schedule – New Year's Day\n", - " Holiday Schedule – MLK Day\n", " ...\n", " sum_unlinked_passenger_trips_upt\n", " score_text - Veterans Day (Observed)\n", @@ -1917,12 +1928,12 @@ " NaN\n", " LA Metro Bus Schedule\n", " 3458.0\n", + " Current\n", " 90154\n", " True\n", " Reduced service\n", " Reduced service\n", " Reduced service\n", - " Regular service\n", " ...\n", " 1.999841e+08\n", " Regular service\n", @@ -1937,21 +1948,21 @@ " \n", " \n", "\n", - "

1 rows × 28 columns

\n", + "

1 rows × 29 columns

\n", "" ], "text/plain": [ " Name Notes gtfs_dataset_name \\\n", "65 LA Metro Bus NaN LA Metro Bus Schedule \n", "\n", - " Total VOMS (NTD) (from Provider) ntd_id_2022 Customer Facing \\\n", - "65 3458.0 90154 True \n", + " Total VOMS (NTD) (from Provider) Holiday Website Status ntd_id_2022 \\\n", + "65 3458.0 Current 90154 \n", "\n", - " Holiday Schedule – Thanksgiving Day Holiday Schedule – Christmas Day \\\n", - "65 Reduced service Reduced service \n", + " Customer Facing Holiday Schedule – Thanksgiving Day \\\n", + "65 True Reduced service \n", "\n", - " Holiday Schedule – New Year's Day Holiday Schedule – MLK Day ... \\\n", - "65 Reduced service Regular service ... \n", + " Holiday Schedule – Christmas Day Holiday Schedule – New Year's Day ... \\\n", + "65 Reduced service Reduced service ... \n", "\n", " sum_unlinked_passenger_trips_upt score_text - Veterans Day (Observed) \\\n", "65 1.999841e+08 Regular service \n", @@ -1962,13 +1973,13 @@ " score_text - Christmas Day score_text - New Year's Day \\\n", "65 Reduced service Reduced service \n", "\n", - " score_text - MLK Day score_text - Veterans Day score_text - Christmas Eve \\\n", - "65 Regular service Regular service Regular service \n", + " score_text - MLK Day score_text - Veterans Day score_text - Christmas Eve \\\n", + "65 Regular service Regular service Regular service \n", "\n", - " score_text - New Year's Eve \n", - "65 Regular service \n", + " score_text - New Year's Eve \n", + "65 Regular service \n", "\n", - "[1 rows x 28 columns]" + "[1 rows x 29 columns]" ] }, "execution_count": 30, @@ -1996,6 +2007,75 @@ { "cell_type": "code", "execution_count": 32, + "id": "eae65c3a-8e31-4afc-b5b9-2fa013850017", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
sum_unlinked_passenger_trips_upt
Holiday Website Status
Current1880355
Off-Season67
Old519
\n", + "
" + ], + "text/plain": [ + " sum_unlinked_passenger_trips_upt\n", + "Holiday Website Status \n", + "Current 1880355\n", + "Off-Season 67\n", + "Old 519" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df[['Holiday Website Status','sum_unlinked_passenger_trips_upt']].groupby('Holiday Website Status').sum().div(365).round().astype(int)\n", + "# df[['Holiday Website Status','sum_unlinked_passenger_trips_upt']].groupby('Holiday Website Status').sum().plot.bar()" + ] + }, + { + "cell_type": "code", + "execution_count": 33, "id": "be11b4cd-f144-4b95-ad75-f73fd5dfad4f", "metadata": {}, "outputs": [], @@ -2015,7 +2095,7 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 34, "id": "d55bc591-e918-4182-90d7-aff1299f6f0b", "metadata": {}, "outputs": [ @@ -2265,7 +2345,7 @@ "MLK Day 428287598.0 " ] }, - "execution_count": 33, + "execution_count": 34, "metadata": {}, "output_type": "execute_result" } @@ -2286,7 +2366,7 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 35, "id": "a76a2d0d-7eae-46a3-bf9e-64702f3d6a2f", "metadata": {}, "outputs": [], @@ -2310,7 +2390,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 36, "id": "391db97d-06b2-4274-a1e4-587cb27fac71", "metadata": {}, "outputs": [ @@ -2423,7 +2503,7 @@ "MLK Day 23369 " ] }, - "execution_count": 35, + "execution_count": 36, "metadata": {}, "output_type": "execute_result" } @@ -2434,7 +2514,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 37, "id": "d10185bc-d049-48f8-8c23-1ae2e188ca32", "metadata": {}, "outputs": [ From e01690902b7420d21c94562e186e52f93c0cb042 Mon Sep 17 00:00:00 2001 From: V Date: Fri, 12 Jul 2024 23:44:32 +0000 Subject: [PATCH 3/3] Redoing website status impact calculation to account for missing orgs --- holiday_service_research/funcs_vars.py | 2 +- .../holiday_research.ipynb | 137 +--- .../website_status_impact.ipynb | 763 ++++++++++++++++++ 3 files changed, 798 insertions(+), 104 deletions(-) create mode 100644 holiday_service_research/website_status_impact.ipynb diff --git a/holiday_service_research/funcs_vars.py b/holiday_service_research/funcs_vars.py index 23bb8f59a..eb66766b3 100644 --- a/holiday_service_research/funcs_vars.py +++ b/holiday_service_research/funcs_vars.py @@ -136,7 +136,7 @@ def plot_confusion_matrices(df, y_true, y_pred, title): plt.ylabel('GTFS Service Levels (% of agencies)', fontweight='bold') plt.title(title, fontweight='bold') file = title - plt.savefig(f"plots/{file}.png") + plt.savefig(f"{file}.png") # return cm, df_cm excel_col_order = ['Name', 'Notes', 'gtfs_dataset_name', diff --git a/holiday_service_research/holiday_research.ipynb b/holiday_service_research/holiday_research.ipynb index 25c20396c..6bcc4b3b6 100644 --- a/holiday_service_research/holiday_research.ipynb +++ b/holiday_service_research/holiday_research.ipynb @@ -85,9 +85,9 @@ "Index(['id', 'Name', 'Notes', 'Provider', 'website', 'Service Type', 'Mode',\n", " 'Rider Requirements', 'Currently Operating', 'Funding Sources',\n", " ...\n", - " 'Product: Payments', 'Deprecated Date', 'Next Steps',\n", + " 'Start Date', 'Product: Payments', 'Deprecated Date', 'Next Steps',\n", " 'New Contact Info (from USDOT)', 'Context from Juliet', 'Season Start',\n", - " 'Season End', 'organizations 2', 'eligibility programs', 'Start Date'],\n", + " 'Season End', 'organizations 2', 'eligibility programs'],\n", " dtype='object', length=123)\n" ] } @@ -325,66 +325,66 @@ " \n", " 0\n", " 2022\n", - " 90003\n", - " San Francisco Bay Area Rapid Transit District\n", + " 90079\n", + " SunLine Transit Agency\n", " Full Reporter\n", " Annual Total\n", - " 38224072.0\n", + " 2298805.0\n", " \n", " \n", " 1\n", " 2022\n", - " 90004\n", - " Golden Empire Transit District\n", + " 90200\n", + " Kings County Area Public Transit Agency\n", " Full Reporter\n", " Annual Total\n", - " 3201046.0\n", + " 490448.0\n", " \n", " \n", " 2\n", " 2022\n", - " 90006\n", - " Santa Cruz Metropolitan Transit District\n", + " 90196\n", + " County of Placer\n", " Full Reporter\n", " Annual Total\n", - " 2837891.0\n", + " 683109.0\n", " \n", " \n", " 3\n", " 2022\n", - " 90008\n", - " City of Santa Monica\n", + " 90233\n", + " Yuma County Intergovernmental Public Transport...\n", " Full Reporter\n", " Annual Total\n", - " 6333923.0\n", + " 354065.0\n", " \n", " \n", " 4\n", " 2022\n", - " 90009\n", - " San Mateo County Transit District\n", + " 90154\n", + " Los Angeles County Metropolitan Transportation...\n", " Full Reporter\n", " Annual Total\n", - " 7128074.0\n", + " 254688124.0\n", " \n", " \n", "\n", "" ], "text/plain": [ - " year ntd_id_2022 agency_name \\\n", - "0 2022 90003 San Francisco Bay Area Rapid Transit District \n", - "1 2022 90004 Golden Empire Transit District \n", - "2 2022 90006 Santa Cruz Metropolitan Transit District \n", - "3 2022 90008 City of Santa Monica \n", - "4 2022 90009 San Mateo County Transit District \n", + " year ntd_id_2022 agency_name \\\n", + "0 2022 90079 SunLine Transit Agency \n", + "1 2022 90200 Kings County Area Public Transit Agency \n", + "2 2022 90196 County of Placer \n", + "3 2022 90233 Yuma County Intergovernmental Public Transport... \n", + "4 2022 90154 Los Angeles County Metropolitan Transportation... \n", "\n", " reporter_type time_period sum_unlinked_passenger_trips_upt \n", - "0 Full Reporter Annual Total 38224072.0 \n", - "1 Full Reporter Annual Total 3201046.0 \n", - "2 Full Reporter Annual Total 2837891.0 \n", - "3 Full Reporter Annual Total 6333923.0 \n", - "4 Full Reporter Annual Total 7128074.0 " + "0 Full Reporter Annual Total 2298805.0 \n", + "1 Full Reporter Annual Total 490448.0 \n", + "2 Full Reporter Annual Total 683109.0 \n", + "3 Full Reporter Annual Total 354065.0 \n", + "4 Full Reporter Annual Total 254688124.0 " ] }, "execution_count": 7, @@ -2007,75 +2007,6 @@ { "cell_type": "code", "execution_count": 32, - "id": "eae65c3a-8e31-4afc-b5b9-2fa013850017", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
sum_unlinked_passenger_trips_upt
Holiday Website Status
Current1880355
Off-Season67
Old519
\n", - "
" - ], - "text/plain": [ - " sum_unlinked_passenger_trips_upt\n", - "Holiday Website Status \n", - "Current 1880355\n", - "Off-Season 67\n", - "Old 519" - ] - }, - "execution_count": 32, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df[['Holiday Website Status','sum_unlinked_passenger_trips_upt']].groupby('Holiday Website Status').sum().div(365).round().astype(int)\n", - "# df[['Holiday Website Status','sum_unlinked_passenger_trips_upt']].groupby('Holiday Website Status').sum().plot.bar()" - ] - }, - { - "cell_type": "code", - "execution_count": 33, "id": "be11b4cd-f144-4b95-ad75-f73fd5dfad4f", "metadata": {}, "outputs": [], @@ -2095,7 +2026,7 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 33, "id": "d55bc591-e918-4182-90d7-aff1299f6f0b", "metadata": {}, "outputs": [ @@ -2345,7 +2276,7 @@ "MLK Day 428287598.0 " ] }, - "execution_count": 34, + "execution_count": 33, "metadata": {}, "output_type": "execute_result" } @@ -2366,7 +2297,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 34, "id": "a76a2d0d-7eae-46a3-bf9e-64702f3d6a2f", "metadata": {}, "outputs": [], @@ -2390,7 +2321,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 35, "id": "391db97d-06b2-4274-a1e4-587cb27fac71", "metadata": {}, "outputs": [ @@ -2503,7 +2434,7 @@ "MLK Day 23369 " ] }, - "execution_count": 36, + "execution_count": 35, "metadata": {}, "output_type": "execute_result" } @@ -2514,7 +2445,7 @@ }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 36, "id": "d10185bc-d049-48f8-8c23-1ae2e188ca32", "metadata": {}, "outputs": [ diff --git a/holiday_service_research/website_status_impact.ipynb b/holiday_service_research/website_status_impact.ipynb new file mode 100644 index 000000000..61da1b242 --- /dev/null +++ b/holiday_service_research/website_status_impact.ipynb @@ -0,0 +1,763 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "04566d29-48b9-4959-bf34-c09e6f3a7f4b", + "metadata": {}, + "source": [ + "Notebook to produce data regarding 2023 Holiday Service:\n", + "https://caltrans.sharepoint.com/:w:/s/DOTPMPHQ-DataandDigitalServices/EVEcAgAwsK1AhL7pQDa22TcBlLF5ZLF-SYOGORhrQrIOCA?e=BX6lkA\n", + "\n", + "Find the total org impact of having missing holiday information using the orgs table, not the services table." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "d592f475-1934-4dce-a238-7588cb0183cc", + "metadata": {}, + "outputs": [], + "source": [ + "%load_ext autoreload\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "e50e1057-525e-489f-8e26-9b5bdb58c6ce", + "metadata": {}, + "outputs": [], + "source": [ + "%autoreload 2\n", + "\n", + "from dotenv import load_dotenv\n", + "import os\n", + "\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import pandas as pd\n", + "from pyairtable import Api\n", + "from sklearn.metrics import confusion_matrix\n", + "\n", + "from funcs_vars import excel_col_order, holiday_columns, holidays_plus_ref, text_data_cols, plot_confusion_matrices\n", + "\n", + "load_dotenv()\n", + "api = Api(os.getenv('AIRTABLE_TOKEN'))\n", + "\n", + "os.environ[\"CALITP_BQ_MAX_BYTES\"] = str(20_000_000_000)\n", + "from calitp_data_analysis.sql import query_sql" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "edd2b5cc-e11b-4434-bee2-381fb3a91bc1", + "metadata": {}, + "outputs": [], + "source": [ + "# Trying to stay consistent with \n", + "# https://github.com/cal-itp/data-infra/blob/main/airflow/plugins/operators/airtable_to_gcs.py\n", + "def all_rows_as_df(base_id, table_name):\n", + " all_rows = api.table(base_id=base_id, table_name=table_name).all()\n", + "\n", + " df = pd.DataFrame(\n", + " [\n", + " {\"id\":row[\"id\"], **row[\"fields\"]}\n", + " for row in all_rows\n", + " ]\n", + " )\n", + " return df\n", + "\n", + "def takeout_list(x):\n", + " if x is not np.nan:\n", + " return x[0]\n", + "\n", + "CALIFORNIA_TRANSIT_ID = \"appPnJWrQ7ui4UmIl\"\n", + "ORGS_ID = 'tblFsd8D5oFRqep8Z'" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "26f5b815-f539-4d86-9fb9-97f1b1f5c93b", + "metadata": {}, + "outputs": [], + "source": [ + "orgs_df = all_rows_as_df(CALIFORNIA_TRANSIT_ID, ORGS_ID)\n", + "orgs_df = orgs_df.loc[~orgs_df['ntd_id_2022'].isnull(),]\n", + "orgs_df = orgs_df.loc[~orgs_df['Holiday Website Status'].isnull(),]" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "7a72be17-4122-47ef-a031-61a0144e42a7", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "160" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "orgs_df['ntd_id_2022'].nunique()" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "6dfef3f0-5de8-4b02-a956-c339afdafa81", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Current 143\n", + "Missing 12\n", + "Old 3\n", + "Off-Season 2\n", + "Name: Holiday Website Status, dtype: int64" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "orgs_df['Holiday Website Status'].value_counts()" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "89be9a52-d326-4eb8-b4a4-388f25ae478b", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ntd_id_2022Holiday Website Status
190023Current
790281Missing
1790027Current
2590267Current
2791088Current
.........
134990121Current
136891093Current
138199424Current
138691059Current
139391095Current
\n", + "

160 rows × 2 columns

\n", + "
" + ], + "text/plain": [ + " ntd_id_2022 Holiday Website Status\n", + "1 90023 Current\n", + "7 90281 Missing\n", + "17 90027 Current\n", + "25 90267 Current\n", + "27 91088 Current\n", + "... ... ...\n", + "1349 90121 Current\n", + "1368 91093 Current\n", + "1381 99424 Current\n", + "1386 91059 Current\n", + "1393 91095 Current\n", + "\n", + "[160 rows x 2 columns]" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "orgs_df[['ntd_id_2022','Holiday Website Status']]" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "ef055f55-13d7-42b0-9a33-c204e20896fa", + "metadata": {}, + "outputs": [], + "source": [ + "ntd_ids = list(set(orgs_df['ntd_id_2022'].dropna()))\n", + "ntd_ids_for_query = ','.join(map(\"'{0}'\".format, ntd_ids))" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "357721d8-2a9c-4a9b-8cc0-64ae2ea6ba45", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
yearntd_id_2022agency_namereporter_typetime_periodsum_unlinked_passenger_trips_upt
0202290079SunLine Transit AgencyFull ReporterAnnual Total2298805.0
1202290200Kings County Area Public Transit AgencyFull ReporterAnnual Total490448.0
2202290196County of PlacerFull ReporterAnnual Total683109.0
3202290233Yuma County Intergovernmental Public Transport...Full ReporterAnnual Total354065.0
4202290154Los Angeles County Metropolitan Transportation...Full ReporterAnnual Total254688124.0
\n", + "
" + ], + "text/plain": [ + " year ntd_id_2022 agency_name \\\n", + "0 2022 90079 SunLine Transit Agency \n", + "1 2022 90200 Kings County Area Public Transit Agency \n", + "2 2022 90196 County of Placer \n", + "3 2022 90233 Yuma County Intergovernmental Public Transport... \n", + "4 2022 90154 Los Angeles County Metropolitan Transportation... \n", + "\n", + " reporter_type time_period sum_unlinked_passenger_trips_upt \n", + "0 Full Reporter Annual Total 2298805.0 \n", + "1 Full Reporter Annual Total 490448.0 \n", + "2 Full Reporter Annual Total 683109.0 \n", + "3 Full Reporter Annual Total 354065.0 \n", + "4 Full Reporter Annual Total 254688124.0 " + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "upt = query_sql(f\"\"\"\n", + "SELECT year, ntd_id as ntd_id_2022, agency_name, reporter_type, time_period, sum(unlinked_passenger_trips__upt_) as sum_unlinked_passenger_trips_upt \n", + "FROM `cal-itp-data-infra.mart_ntd.dim_annual_ntd_agency_service` \n", + "where ntd_id in ({ntd_ids_for_query})\n", + "and time_period = 'Annual Total'\n", + "and year = 2022\n", + "group by 1,2,3,4,5;\n", + "\"\"\", as_df=True)\n", + "upt.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "52f1673d-29ba-4504-b5ec-9a9ee30956a7", + "metadata": {}, + "outputs": [], + "source": [ + "df = pd.merge(orgs_df[['Name','ntd_id_2022','Holiday Website Status']], upt[['ntd_id_2022','agency_name','sum_unlinked_passenger_trips_upt']],how='left',indicator=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "1bd1dd14-c025-475b-b63c-0875883e9428", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "6" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df['sum_unlinked_passenger_trips_upt'].isnull().sum()" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "8afd75a6-392a-429b-ab98-0aca8900c22c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(160, 6)" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "d59b3bc1-b284-47db-a22f-e117b0dcfe53", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Namentd_id_2022Holiday Website Statusagency_namesum_unlinked_passenger_trips_upt_merge
30City of El Segundo99449Off-SeasonNaNNaNleft_only
66Susanville Indian Rancheria99256MissingNaNNaNleft_only
105City of Duarte90264CurrentNaNNaNleft_only
106City of Elk Grove90205CurrentNaNNaNleft_only
112City of Sierra Madre99447MissingNaNNaNleft_only
124City of Lawndale90280CurrentNaNNaNleft_only
\n", + "
" + ], + "text/plain": [ + " Name ntd_id_2022 Holiday Website Status \\\n", + "30 City of El Segundo 99449 Off-Season \n", + "66 Susanville Indian Rancheria 99256 Missing \n", + "105 City of Duarte 90264 Current \n", + "106 City of Elk Grove 90205 Current \n", + "112 City of Sierra Madre 99447 Missing \n", + "124 City of Lawndale 90280 Current \n", + "\n", + " agency_name sum_unlinked_passenger_trips_upt _merge \n", + "30 NaN NaN left_only \n", + "66 NaN NaN left_only \n", + "105 NaN NaN left_only \n", + "106 NaN NaN left_only \n", + "112 NaN NaN left_only \n", + "124 NaN NaN left_only " + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.loc[df['sum_unlinked_passenger_trips_upt'].isnull(),]" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "0288f733-a62a-4a47-b14a-22a16f9b5d44", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Namentd_id_2022Holiday Website Statusagency_namesum_unlinked_passenger_trips_upt_merge
0Long Beach Transit90023CurrentLong Beach Transit17409861.0both
1City of Lynwood90281MissingCity of Lynwood114161.0both
2City of Fresno90027CurrentCity of Fresno7120464.0both
3City of Huntington Park90267CurrentCity of Huntington Park143920.0both
4Glenn County91088CurrentGlenn Transit Service19210.0both
\n", + "
" + ], + "text/plain": [ + " Name ntd_id_2022 Holiday Website Status \\\n", + "0 Long Beach Transit 90023 Current \n", + "1 City of Lynwood 90281 Missing \n", + "2 City of Fresno 90027 Current \n", + "3 City of Huntington Park 90267 Current \n", + "4 Glenn County 91088 Current \n", + "\n", + " agency_name sum_unlinked_passenger_trips_upt _merge \n", + "0 Long Beach Transit 17409861.0 both \n", + "1 City of Lynwood 114161.0 both \n", + "2 City of Fresno 7120464.0 both \n", + "3 City of Huntington Park 143920.0 both \n", + "4 Glenn Transit Service 19210.0 both " + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "76617c8b-3204-4eb1-9f74-291c7581e2ba", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
sum_unlinked_passenger_trips_upt
Holiday Website Status
Current1881743
Missing23468
Off-Season67
Old571
\n", + "
" + ], + "text/plain": [ + " sum_unlinked_passenger_trips_upt\n", + "Holiday Website Status \n", + "Current 1881743\n", + "Missing 23468\n", + "Off-Season 67\n", + "Old 571" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df[['Holiday Website Status','sum_unlinked_passenger_trips_upt']].groupby('Holiday Website Status').sum().div(365).round().astype(int)\n", + "# df[['Holiday Website Status','sum_unlinked_passenger_trips_upt']].groupby('Holiday Website Status').sum().plot.bar()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.9.13" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}