From 3b4353cdb5231e29ae0da0619a83cdbb8d9834e6 Mon Sep 17 00:00:00 2001 From: brisson0916 Date: Tue, 2 Jun 2026 14:15:36 +0800 Subject: [PATCH 1/3] main.ipynb: clean columns district and working encoded_transport --- .gitignore | 2 + main.ipynb | 1187 ++++++++++++++++++++++++++++++++++++++ pyproject.toml | 1 + submission/manifest.json | 6 + uv.lock | 420 +++++++++++++- 5 files changed, 1615 insertions(+), 1 deletion(-) create mode 100644 main.ipynb create mode 100644 submission/manifest.json diff --git a/.gitignore b/.gitignore index c9a03a4..ed79207 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,5 @@ admin/opentofu/.terraform.tfstate.lock.info admin/opentofu/generated/ admin/opentofu/terraform.tfstate* admin/opentofu/terraform.tfvars + +team_private_key.pem diff --git a/main.ipynb b/main.ipynb new file mode 100644 index 0000000..1d15775 --- /dev/null +++ b/main.ipynb @@ -0,0 +1,1187 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 933, + "id": "76f1553e", + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import numpy as np\n", + "import re\n", + "from urllib.parse import unquote\n", + "\n", + "\n", + "import sys\n", + "sys.path.append(\"./submission\")\n", + "import clean\n", + "\n", + "df = pd.read_csv(\"./data/test_features.csv\")\n", + "df = df[['origin_station',\n", + " 'destination_station',\n", + " 'district',\n", + " 'encoded_transport',\n", + " 'day_of_week',\n", + " 'is_holiday',\n", + " 'weather_condition',\n", + " 'country_code']]" + ] + }, + { + "cell_type": "markdown", + "id": "59f0d260", + "metadata": {}, + "source": [ + "Lucciano: Cleaning Origin and Destination" + ] + }, + { + "cell_type": "code", + "execution_count": 934, + "id": "63db2f09", + "metadata": {}, + "outputs": [], + "source": [ + "# Canonical station -> ordered regexes matched against the SQUASHED key\n", + "# (lowercased, url-decoded, wrappers stripped, all non-alphanumerics removed).\n", + "# Order matters: more specific patterns first. ^x$ pins the short codes.\n", + "_STATION_RULES = [\n", + " (\"Causeway Bay\", r\"causewaybay|cwbhub|^cwb$|^cb$\"),\n", + " (\"Central\", r\"central|stncentral|censt|^cstation$|^cstn$|^cs$\"),\n", + " (\"Admiralty\", r\"admiralt|admxfer|^adm$\"),\n", + " (\"Sha Tin\", r\"shatin|shatinterm|^stin$|^stn$|^st$\"),\n", + " (\"Mong Kok\", r\"mongkok|mkhub|^mk$\"),\n", + " (\"Tsim Sha Tsui\", r\"tsimshatsui|tsteast|^tst$\"),\n", + " (\"North Point\", r\"northpoint|northpt|npferry|^np$\"),\n", + " (\"Tsuen Wan\", r\"tsuenwan|tswline|^twn$|^tswan$|^tw$\"),\n", + " (\"Kennedy Town\", r\"kennedyt|ktownstop|^ktown$|^kt$\"),\n", + " (\"Wan Chai\", r\"wanchai|wanchaistop|^wchai$|^wc$\"),\n", + "]\n", + "# Markers/non-stations to skip. unk = unknown placeholder; depot/workshop/audithub\n", + "# are internal sites, not passenger stations -> treated as missing.\n", + "_NOISE = re.compile(r\"^(unk|audithub|depot|workshop)$\")\n", + "\n", + "\n", + "def clean_station(s: pd.Series) -> pd.Series:\n", + " def clean_value(v):\n", + " if not isinstance(v, str):\n", + " return pd.NA\n", + " x = unquote(unquote(v)).strip().lower() # decode (handles %2520), trim\n", + " for tok in re.split(r\"[:|=\\-]+\", x):\n", + " key = re.sub(r\"[^a-z0-9]\", \"\", tok) # squash: drop spaces/./%20 etc\n", + " if not key or _NOISE.match(key):\n", + " continue\n", + " for canon, pat in _STATION_RULES:\n", + " if re.search(pat, key):\n", + " return canon\n", + " return pd.NA # no station token -> missing\n", + "\n", + " return s.map(clean_value)\n", + "\n", + "df['origin_station'] = clean_station(df['origin_station'])\n", + "df['destination_station'] = clean_station(df['destination_station'])" + ] + }, + { + "cell_type": "markdown", + "id": "2b19ab53", + "metadata": {}, + "source": [ + "Cleaning District" + ] + }, + { + "cell_type": "code", + "execution_count": 935, + "id": "f84f4f73", + "metadata": {}, + "outputs": [], + "source": [ + "# Clean district column values of prefix/suffix patterns\n", + "\n", + "def clean_district(df):\n", + " # Strip whitespace\n", + " df['district'] = df['district'].str.strip()\n", + " \n", + " # Remove prefix patterns (e.g., \"D123\" → \"123\")\n", + " prefix_pattern = r'(D|zone|hold|district|Legacy|region|Leg|LEG)[^a-zA-Z0-9]+'\n", + " df['district'] = df['district'].str.replace(prefix_pattern, '', regex=True)\n", + " \n", + " # Remove suffix patterns (e.g., \"central_zone\" → \"central\")\n", + " suffix_pattern = r'[_|](?:new|core|zone|cluster|sector|OPS)'\n", + " df['district'] = df['district'].str.replace(suffix_pattern, '', regex=True)\n", + " \n", + " # Normalize missing/weird values into NaN\n", + " unknown_values = [\n", + " 'Legacy', 'unknown', '??', 'mismatch', 'Null', 'legacy',\n", + " 'Internal', 'operations', 'audit', 'eh', 'unk', ''\n", + " ]\n", + " df['district'] = df['district'].str.replace(r'^(operations|audit|unk|eh)\\s*$', '', regex=True, case=False)\n", + "\n", + " df['district'] = df['district'].replace(unknown_values, np.nan)\n", + "\n", + " return df\n", + "\n", + "df = clean_district(df)" + ] + }, + { + "cell_type": "code", + "execution_count": 936, + "id": "3be9e915", + "metadata": {}, + "outputs": [], + "source": [ + "#map district variants into unified category\n", + "\n", + "district_variant_mapping = [\n", + " (\"Central and Western\", r\"cw|cwbhub|^cwb$|^cb$|central_and_western|central and western\"),\n", + " (\"Tsuen Wan\", r\"tw|tsw|tsuen_wan|tsuen wan\"),\n", + " (\"Yau Tsim Mong\", r\"YTM|ytm|yau tsim mong|yau_tsim_mong\"),\n", + " (\"Sha Tin\", r\"ST|sha tin|shatin|st|sha_tin\"),\n", + " (\"Eastern\", r\"eastern|east_harbour\"), \n", + " (\"Wan Chai\", r\"wanchai|wanchaistop|^wchai$|^wc$|wan chai|wan_chai\")\n", + "]\n", + "\n", + "def map_district(value):\n", + " if pd.isna(value):\n", + " return value\n", + " value = str(value).lower().strip()\n", + " for full_name, pattern in district_variant_mapping:\n", + " if pattern and re.search(pattern, value):\n", + " return full_name\n", + " return value # return original if no match\n", + "\n", + "df['district'] = df['district'].apply(map_district)\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 937, + "id": "9a9bc0f9", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "district\n", + "Central and Western 543\n", + "Yau Tsim Mong 431\n", + "Wan Chai 405\n", + "Sha Tin 281\n", + "Tsuen Wan 193\n", + "NaN 127\n", + "Eastern 113\n", + "Name: count, dtype: int64" + ] + }, + "execution_count": 937, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# map district NANs from known origin station:\n", + "\n", + "station_district_mapping = {\n", + " 'Central and Western': ('Central', 'Admiralty', 'Kennedy Town'),\n", + " 'Wan Chai': ('Wan Chai', 'Causeway Bay'),\n", + " 'Yau Tsim Mong': ('Mong Kok', 'Tsim Sha Tsui'),\n", + " 'Sha Tin': ('Sha Tin',),\n", + " 'Tsuen Wan': ('Tsuen Wan',),\n", + " 'Eastern': ('North Point',)\n", + "}\n", + "\n", + "\n", + "def fill_district_from_station(df, station_col='origin_station', district_col='district'):\n", + " # Build reverse lookup: station -> district\n", + " station_to_district = {\n", + " station.lower(): district\n", + " for district, stations in station_district_mapping.items()\n", + " for station in stations\n", + " }\n", + " \n", + " # Fill nulls with station lookup\n", + " df[district_col] = df[district_col].fillna(\n", + " df[station_col].str.lower().str.strip().map(station_to_district)\n", + " )\n", + " return df\n", + "\n", + "# Usage\n", + "df = fill_district_from_station(df)\n", + "\n", + "df['district'].value_counts(dropna=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 938, + "id": "8bc21583", + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
origin_stationdestination_stationdistrict
1424Causeway BayCentralWan Chai
585CentralTsuen WanCentral and Western
1030Causeway BayMong KokWan Chai
1377Kennedy TownCentralCentral and Western
1723Kennedy TownMong KokCentral and Western
1916NaNNaNNaN
910Causeway BayCentralWan Chai
527Kennedy TownTsim Sha TsuiCentral and Western
1020Tsuen WanWan ChaiTsuen Wan
1888North PointTsim Sha TsuiSha Tin
26Mong KokCentralYau Tsim Mong
1217Wan ChaiNorth PointWan Chai
1197AdmiraltyTsuen WanCentral and Western
122Tsuen WanMong KokTsuen Wan
202Mong KokNorth PointYau Tsim Mong
154Tsim Sha TsuiMong KokYau Tsim Mong
364Kennedy TownSha TinCentral and Western
450Mong KokNorth PointYau Tsim Mong
298CentralCauseway BayCentral and Western
1999Sha TinTsim Sha TsuiSha Tin
959North PointTsuen WanEastern
341North PointWan ChaiEastern
790Mong KokCauseway BayYau Tsim Mong
1355Wan ChaiTsuen WanWan Chai
294CentralCauseway BayCentral and Western
1463North PointAdmiraltyEastern
1026North PointCentralEastern
116Wan ChaiMong KokWan Chai
582Causeway BayWan ChaiWan Chai
83Tsuen WanWan ChaiTsuen Wan
\n", + "
" + ], + "text/plain": [ + " origin_station destination_station district\n", + "1424 Causeway Bay Central Wan Chai\n", + "585 Central Tsuen Wan Central and Western\n", + "1030 Causeway Bay Mong Kok Wan Chai\n", + "1377 Kennedy Town Central Central and Western\n", + "1723 Kennedy Town Mong Kok Central and Western\n", + "1916 NaN NaN NaN\n", + "910 Causeway Bay Central Wan Chai\n", + "527 Kennedy Town Tsim Sha Tsui Central and Western\n", + "1020 Tsuen Wan Wan Chai Tsuen Wan\n", + "1888 North Point Tsim Sha Tsui Sha Tin\n", + "26 Mong Kok Central Yau Tsim Mong\n", + "1217 Wan Chai North Point Wan Chai\n", + "1197 Admiralty Tsuen Wan Central and Western\n", + "122 Tsuen Wan Mong Kok Tsuen Wan\n", + "202 Mong Kok North Point Yau Tsim Mong\n", + "154 Tsim Sha Tsui Mong Kok Yau Tsim Mong\n", + "364 Kennedy Town Sha Tin Central and Western\n", + "450 Mong Kok North Point Yau Tsim Mong\n", + "298 Central Causeway Bay Central and Western\n", + "1999 Sha Tin Tsim Sha Tsui Sha Tin\n", + "959 North Point Tsuen Wan Eastern\n", + "341 North Point Wan Chai Eastern\n", + "790 Mong Kok Causeway Bay Yau Tsim Mong\n", + "1355 Wan Chai Tsuen Wan Wan Chai\n", + "294 Central Causeway Bay Central and Western\n", + "1463 North Point Admiralty Eastern\n", + "1026 North Point Central Eastern\n", + "116 Wan Chai Mong Kok Wan Chai\n", + "582 Causeway Bay Wan Chai Wan Chai\n", + "83 Tsuen Wan Wan Chai Tsuen Wan" + ] + }, + "execution_count": 938, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df[['origin_station','destination_station','district']].sample(30)" + ] + }, + { + "cell_type": "markdown", + "id": "82df77a7", + "metadata": {}, + "source": [ + "Cleaning Day of Week" + ] + }, + { + "cell_type": "code", + "execution_count": 939, + "id": "60b0a2db", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "day_of_week\n", + "Fri 366\n", + "Thu 329\n", + "Wed 324\n", + "Mon 308\n", + "Tue 290\n", + "Sat 281\n", + "Sun 195\n", + "Name: count, dtype: int64" + ] + }, + "execution_count": 939, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df['day_of_week'] = df['day_of_week'].str.title()\n", + "df['day_of_week'].value_counts(dropna=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 940, + "id": "534d4e8a", + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
origin_stationdestination_stationdistrictencoded_transportday_of_weekis_holidayweather_conditioncountry_code
0Sha TinTsuen WanSha Tintram_loc_std_citybus(src=endcap)(batch=L2)Fri0NaNUNK
1Tsuen WanKennedy TownTsuen Wantype=tram-xhbr;mode=loc;tier=missing;op=unknownThu0NaN852
2Causeway BayWan ChaiWan Chai[tram][run=loc][tier=std][op=citybus][sys=L2]Wed0NaNterritory-hk
3AdmiraltyCauseway BayCentral and Western[bus-ngt][run=exp][tier=std][op=citybus][sys=L2]Thu0wx_unknownlegacy
4North PointCentralSha TinL2::bus::exp::std::citybus::tailSat1NaNlegacy
...........................
2088NaNNaNSha Tinmaintenance_shiftSun0SUNNYTST
2089Wan ChaiCentralYau Tsim Mongfeed=OPS|kind=tram-ngt|run=exp|tier=std|op=cit...Sat0SUNNYcc=852|OPS
2090Sha TinTsuen WanWan Chaiferry__MISS__ferryhkTue0heavy-rnlegacy-null
2091Mong KokWan ChaiYau Tsim MongL2::tram::exp::std::citybus::tailMon0heavy-rnterritory-hk
2092AdmiraltyKennedy TownCentral and Westernvendor(kind=bus,mode=exp,tier=std,op=citybus)Thu0UnknownN/A-HK
\n", + "

2093 rows × 8 columns

\n", + "
" + ], + "text/plain": [ + " origin_station destination_station district \\\n", + "0 Sha Tin Tsuen Wan Sha Tin \n", + "1 Tsuen Wan Kennedy Town Tsuen Wan \n", + "2 Causeway Bay Wan Chai Wan Chai \n", + "3 Admiralty Causeway Bay Central and Western \n", + "4 North Point Central Sha Tin \n", + "... ... ... ... \n", + "2088 NaN NaN Sha Tin \n", + "2089 Wan Chai Central Yau Tsim Mong \n", + "2090 Sha Tin Tsuen Wan Wan Chai \n", + "2091 Mong Kok Wan Chai Yau Tsim Mong \n", + "2092 Admiralty Kennedy Town Central and Western \n", + "\n", + " encoded_transport day_of_week \\\n", + "0 tram_loc_std_citybus(src=endcap)(batch=L2) Fri \n", + "1 type=tram-xhbr;mode=loc;tier=missing;op=unknown Thu \n", + "2 [tram][run=loc][tier=std][op=citybus][sys=L2] Wed \n", + "3 [bus-ngt][run=exp][tier=std][op=citybus][sys=L2] Thu \n", + "4 L2::bus::exp::std::citybus::tail Sat \n", + "... ... ... \n", + "2088 maintenance_shift Sun \n", + "2089 feed=OPS|kind=tram-ngt|run=exp|tier=std|op=cit... Sat \n", + "2090 ferry__MISS__ferryhk Tue \n", + "2091 L2::tram::exp::std::citybus::tail Mon \n", + "2092 vendor(kind=bus,mode=exp,tier=std,op=citybus) Thu \n", + "\n", + " is_holiday weather_condition country_code \n", + "0 0 NaN UNK \n", + "1 0 NaN 852 \n", + "2 0 NaN territory-hk \n", + "3 0 wx_unknown legacy \n", + "4 1 NaN legacy \n", + "... ... ... ... \n", + "2088 0 SUNNY TST \n", + "2089 0 SUNNY cc=852|OPS \n", + "2090 0 heavy-rn legacy-null \n", + "2091 0 heavy-rn territory-hk \n", + "2092 0 Unknown N/A-HK \n", + "\n", + "[2093 rows x 8 columns]" + ] + }, + "execution_count": 940, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df" + ] + }, + { + "cell_type": "code", + "execution_count": 941, + "id": "c69375a5", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['origin_station',\n", + " 'destination_station',\n", + " 'district',\n", + " 'transport_type',\n", + " 'transport_detail',\n", + " 'mode',\n", + " 'service_level',\n", + " 'operator',\n", + " 'day_of_week',\n", + " 'is_holiday',\n", + " 'weather_condition',\n", + " 'country_code']" + ] + }, + "execution_count": 941, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "clean.SUBMISSION_FEATURES" + ] + }, + { + "cell_type": "code", + "execution_count": 942, + "id": "30a35039", + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
encoded_transporttransport_typetransport_detailmodeservice_leveloperator
873type:tram|mode:loc|svc:std|owner:citybus|feed=OPStramgenerallocalstandardcitybus
1781maintenance_shiftNaNNaNNaNNaNNaN
856type=tram;mode=loc;tier=missing;op=unknowntramgenerallocalNaNNaN
474OPS::bus|loc|std|kowloon|v2busgeneralNaNNaNkowloon
481UNK::tram::loc::citybustramgeneralNaNNaNcitybus
1580srcfeed::tram::loc::std::citybus::deltatramgeneralNaNNaNNaN
489amb::bus:loc:prem:citybus:??busgenerallocalNaNcitybus
1850kind=bus-apt|kind=alt|run=?|tier=?|op=kowloonbusairportNaNNaNkowloon
178ferry__MISS__ferryhkNaNgeneralNaNNaNferryhk
926type=tram;mode=loc;tier=missing;op=unknowntramgenerallocalNaNNaN
1792type=tram;mode=loc;tier=missing;op=unknowntramgenerallocalNaNNaN
44L2::bus::loc::std::kowloon::tailbusgeneralNaNNaNkowloon
1891srcfeed::bus-apt::exp::std::kowloon::deltabusairportNaNNaNNaN
245UNK::bus-apt::loc::kowloonbusairportNaNNaNkowloon
1128bus-xhbrlocstdkowloonbuscrossharbourNaNNaNkowloon
808UNK::tram::exp::citybustramgeneralNaNNaNcitybus
277UNK::tram::loc::citybustramgeneralNaNNaNcitybus
1284buslocstdkowloonNaNgeneralNaNNaNkowloon
1371tram.loc.prem.citybustramgeneralNaNNaNcitybus
584kind=bus-apt|kind=alt|run=?|tier=?|op=citybusbusairportNaNNaNcitybus
\n", + "
" + ], + "text/plain": [ + " encoded_transport transport_type \\\n", + "873 type:tram|mode:loc|svc:std|owner:citybus|feed=OPS tram \n", + "1781 maintenance_shift NaN \n", + "856 type=tram;mode=loc;tier=missing;op=unknown tram \n", + "474 OPS::bus|loc|std|kowloon|v2 bus \n", + "481 UNK::tram::loc::citybus tram \n", + "1580 srcfeed::tram::loc::std::citybus::delta tram \n", + "489 amb::bus:loc:prem:citybus:?? bus \n", + "1850 kind=bus-apt|kind=alt|run=?|tier=?|op=kowloon bus \n", + "178 ferry__MISS__ferryhk NaN \n", + "926 type=tram;mode=loc;tier=missing;op=unknown tram \n", + "1792 type=tram;mode=loc;tier=missing;op=unknown tram \n", + "44 L2::bus::loc::std::kowloon::tail bus \n", + "1891 srcfeed::bus-apt::exp::std::kowloon::delta bus \n", + "245 UNK::bus-apt::loc::kowloon bus \n", + "1128 bus-xhbrlocstdkowloon bus \n", + "808 UNK::tram::exp::citybus tram \n", + "277 UNK::tram::loc::citybus tram \n", + "1284 buslocstdkowloon NaN \n", + "1371 tram.loc.prem.citybus tram \n", + "584 kind=bus-apt|kind=alt|run=?|tier=?|op=citybus bus \n", + "\n", + " transport_detail mode service_level operator \n", + "873 general local standard citybus \n", + "1781 NaN NaN NaN NaN \n", + "856 general local NaN NaN \n", + "474 general NaN NaN kowloon \n", + "481 general NaN NaN citybus \n", + "1580 general NaN NaN NaN \n", + "489 general local NaN citybus \n", + "1850 airport NaN NaN kowloon \n", + "178 general NaN NaN ferryhk \n", + "926 general local NaN NaN \n", + "1792 general local NaN NaN \n", + "44 general NaN NaN kowloon \n", + "1891 airport NaN NaN NaN \n", + "245 airport NaN NaN kowloon \n", + "1128 crossharbour NaN NaN kowloon \n", + "808 general NaN NaN citybus \n", + "277 general NaN NaN citybus \n", + "1284 general NaN NaN kowloon \n", + "1371 general NaN NaN citybus \n", + "584 airport NaN NaN citybus " + ] + }, + "execution_count": 942, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Parse encoded_transport into 5 columns\n", + "_SPECIAL_NO_TRANSPORT = {\n", + " 'maintenance_shift', 'admin_move', 'staff_shuttle', 'test_run',\n", + " 'unk', 'encoded_transport'\n", + "}\n", + "\n", + "def parse_encoded_transport(s):\n", + " if not isinstance(s, str):\n", + " return {'transport_type': pd.NA, 'transport_detail': pd.NA,\n", + " 'mode': pd.NA, 'service_level': pd.NA, 'operator': pd.NA}\n", + " v = s.strip().lower()\n", + " if v in _SPECIAL_NO_TRANSPORT or not v:\n", + " return {'transport_type': pd.NA, 'transport_detail': pd.NA,\n", + " 'mode': pd.NA, 'service_level': pd.NA, 'operator': pd.NA}\n", + "\n", + " # transport_type\n", + " if re.search(r'\\btram\\b', v):\n", + " transport_type = 'tram'\n", + " elif re.search(r'\\bferry\\b', v):\n", + " transport_type = 'ferry'\n", + " elif re.search(r'\\bbus\\b', v):\n", + " transport_type = 'bus'\n", + " else:\n", + " transport_type = pd.NA\n", + "\n", + " # transport_detail\n", + " m = re.search(r'(tram|ferry|bus)[-]?(apt|ngt|night|xhbr)', v)\n", + " if m:\n", + " detail_map = {'apt': 'airport', 'ngt': 'night', 'night': 'night', 'xhbr': 'crossharbour'}\n", + " transport_detail = detail_map.get(m.group(2), 'general')\n", + " else:\n", + " transport_detail = 'general'\n", + "\n", + " # mode\n", + " m = re.search(r'\\b(?:run|mode)[=:](\\w+)', v)\n", + " if m:\n", + " mode_map = {'loc': 'local', 'exp': 'express'}\n", + " mode = mode_map.get(m.group(1), pd.NA)\n", + " else:\n", + " m = re.search(r'(tram|ferry|bus)[-]?\\w*[:_](\\w+)[:_]', v)\n", + " if m and m.group(2) in ('loc', 'exp'):\n", + " mode = 'local' if m.group(2) == 'loc' else 'express'\n", + " else:\n", + " mode = pd.NA\n", + "\n", + " # service_level\n", + " m = re.search(r'\\b(?:tier|svc)[=:](\\w+)', v)\n", + " if m:\n", + " sl_map = {'std': 'standard', 'prem': 'premium', 'missing': pd.NA}\n", + " service_level = sl_map.get(m.group(1), pd.NA)\n", + " else:\n", + " m = re.search(r'(tram|ferry|bus)[-]?\\w*[:_](\\w+)[:_]', v)\n", + " if m and m.group(2) in ('std', 'prem'):\n", + " service_level = 'standard' if m.group(2) == 'std' else 'premium'\n", + " else:\n", + " service_level = pd.NA\n", + "\n", + " # operator\n", + " m = re.search(r'\\b(?:op|owner)[=:](\\w+)', v)\n", + " if m:\n", + " operator = m.group(1)\n", + " else:\n", + " m = re.search(r'(? extract operator at end\n", + " m = re.search(r'(citybus|kowloon|ferryhk)$', str(operator))\n", + " if m:\n", + " operator = m.group(1)\n", + "\n", + " # Fix truncated operators (missing first letter)\n", + " if operator == 'itybus':\n", + " operator = 'citybus'\n", + " elif operator == 'owloon':\n", + " operator = 'kowloon'\n", + " elif operator == 'erryhk':\n", + " operator = 'ferryhk'\n", + "\n", + " # Normalize garbage/invalid operators to NaN\n", + " invalid_operators = {'unknown', 'delta', 'endcap)(batch', ''}\n", + " if operator in invalid_operators:\n", + " operator = pd.NA\n", + "\n", + " return {'transport_type': transport_type, 'transport_detail': transport_detail,\n", + " 'mode': mode, 'service_level': service_level, 'operator': operator}\n", + "\n", + "parsed = df['encoded_transport'].apply(parse_encoded_transport).apply(pd.Series)\n", + "df = pd.concat([df, parsed], axis=1)\n", + "\n", + "df[['encoded_transport', 'transport_type',\n", + " 'transport_detail',\n", + " 'mode',\n", + " 'service_level',\n", + " 'operator']].sample(20)" + ] + }, + { + "cell_type": "code", + "execution_count": 943, + "id": "ea054597", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "operator\n", + "citybus 802\n", + "kowloon 599\n", + "NaN 438\n", + "ferryhk 254\n", + "Name: count, dtype: int64" + ] + }, + "execution_count": 943, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df['operator'].value_counts(dropna=False).head(30)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "dataclean-workshop", + "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.13.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/pyproject.toml b/pyproject.toml index 68128b4..84d74c4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,6 +5,7 @@ description = "HKPUG data cleaning tournament starter" readme = "README.md" requires-python = ">=3.13" dependencies = [ + "ipykernel>=7.2.0", "pandas>=3.0.2", "scikit-learn>=1.7.2", ] diff --git a/submission/manifest.json b/submission/manifest.json new file mode 100644 index 0000000..da5509a --- /dev/null +++ b/submission/manifest.json @@ -0,0 +1,6 @@ +{ + "team_id": "team-01", + "code_path": "submission/clean.py.cms", + "code_sha256": "filled-by-submission/encrypt_submission.sh", + "notes": "Replace team_id with your assigned team identity before signing." +} diff --git a/uv.lock b/uv.lock index 4ffae69..be9369e 100644 --- a/uv.lock +++ b/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 3 +revision = 2 requires-python = ">=3.13" resolution-markers = [ "python_full_version >= '3.14' and sys_platform == 'win32'", @@ -10,6 +10,69 @@ resolution-markers = [ "python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", ] +[[package]] +name = "appnope" +version = "0.1.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/35/5d/752690df9ef5b76e169e68d6a129fa6d08a7100ca7f754c89495db3c6019/appnope-0.1.4.tar.gz", hash = "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee", size = 4170, upload-time = "2024-02-06T09:43:11.258Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/81/29/5ecc3a15d5a33e31b26c11426c45c501e439cb865d0bff96315d86443b78/appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c", size = 4321, upload-time = "2024-02-06T09:43:09.663Z" }, +] + +[[package]] +name = "asttokens" +version = "3.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/be/a5/8e3f9b6771b0b408517c82d97aed8f2036509bc247d46114925e32fe33f0/asttokens-3.0.1.tar.gz", hash = "sha256:71a4ee5de0bde6a31d64f6b13f2293ac190344478f081c3d1bccfcf5eacb0cb7", size = 62308, upload-time = "2025-11-15T16:43:48.578Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/39/e7eaf1799466a4aef85b6a4fe7bd175ad2b1c6345066aa33f1f58d4b18d0/asttokens-3.0.1-py3-none-any.whl", hash = "sha256:15a3ebc0f43c2d0a50eeafea25e19046c68398e487b9f1f5b517f7c0f40f976a", size = 27047, upload-time = "2025-11-15T16:43:16.109Z" }, +] + +[[package]] +name = "cffi" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pycparser", marker = "implementation_name != 'PyPy'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/eb/56/b1ba7935a17738ae8453301356628e8147c79dbb825bcbc73dc7401f9846/cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529", size = 523588, upload-time = "2025-09-08T23:24:04.541Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4b/8d/a0a47a0c9e413a658623d014e91e74a50cdd2c423f7ccfd44086ef767f90/cffi-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb", size = 185230, upload-time = "2025-09-08T23:23:00.879Z" }, + { url = "https://files.pythonhosted.org/packages/4a/d2/a6c0296814556c68ee32009d9c2ad4f85f2707cdecfd7727951ec228005d/cffi-2.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca", size = 181043, upload-time = "2025-09-08T23:23:02.231Z" }, + { url = "https://files.pythonhosted.org/packages/b0/1e/d22cc63332bd59b06481ceaac49d6c507598642e2230f201649058a7e704/cffi-2.0.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b", size = 212446, upload-time = "2025-09-08T23:23:03.472Z" }, + { url = "https://files.pythonhosted.org/packages/a9/f5/a2c23eb03b61a0b8747f211eb716446c826ad66818ddc7810cc2cc19b3f2/cffi-2.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b", size = 220101, upload-time = "2025-09-08T23:23:04.792Z" }, + { url = "https://files.pythonhosted.org/packages/f2/7f/e6647792fc5850d634695bc0e6ab4111ae88e89981d35ac269956605feba/cffi-2.0.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f93fd8e5c8c0a4aa1f424d6173f14a892044054871c771f8566e4008eaa359d2", size = 207948, upload-time = "2025-09-08T23:23:06.127Z" }, + { url = "https://files.pythonhosted.org/packages/cb/1e/a5a1bd6f1fb30f22573f76533de12a00bf274abcdc55c8edab639078abb6/cffi-2.0.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:dd4f05f54a52fb558f1ba9f528228066954fee3ebe629fc1660d874d040ae5a3", size = 206422, upload-time = "2025-09-08T23:23:07.753Z" }, + { url = "https://files.pythonhosted.org/packages/98/df/0a1755e750013a2081e863e7cd37e0cdd02664372c754e5560099eb7aa44/cffi-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26", size = 219499, upload-time = "2025-09-08T23:23:09.648Z" }, + { url = "https://files.pythonhosted.org/packages/50/e1/a969e687fcf9ea58e6e2a928ad5e2dd88cc12f6f0ab477e9971f2309b57c/cffi-2.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d9b29c1f0ae438d5ee9acb31cadee00a58c46cc9c0b2f9038c6b0b3470877a8c", size = 222928, upload-time = "2025-09-08T23:23:10.928Z" }, + { url = "https://files.pythonhosted.org/packages/36/54/0362578dd2c9e557a28ac77698ed67323ed5b9775ca9d3fe73fe191bb5d8/cffi-2.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6d50360be4546678fc1b79ffe7a66265e28667840010348dd69a314145807a1b", size = 221302, upload-time = "2025-09-08T23:23:12.42Z" }, + { url = "https://files.pythonhosted.org/packages/eb/6d/bf9bda840d5f1dfdbf0feca87fbdb64a918a69bca42cfa0ba7b137c48cb8/cffi-2.0.0-cp313-cp313-win32.whl", hash = "sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27", size = 172909, upload-time = "2025-09-08T23:23:14.32Z" }, + { url = "https://files.pythonhosted.org/packages/37/18/6519e1ee6f5a1e579e04b9ddb6f1676c17368a7aba48299c3759bbc3c8b3/cffi-2.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75", size = 183402, upload-time = "2025-09-08T23:23:15.535Z" }, + { url = "https://files.pythonhosted.org/packages/cb/0e/02ceeec9a7d6ee63bb596121c2c8e9b3a9e150936f4fbef6ca1943e6137c/cffi-2.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91", size = 177780, upload-time = "2025-09-08T23:23:16.761Z" }, + { url = "https://files.pythonhosted.org/packages/92/c4/3ce07396253a83250ee98564f8d7e9789fab8e58858f35d07a9a2c78de9f/cffi-2.0.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fc33c5141b55ed366cfaad382df24fe7dcbc686de5be719b207bb248e3053dc5", size = 185320, upload-time = "2025-09-08T23:23:18.087Z" }, + { url = "https://files.pythonhosted.org/packages/59/dd/27e9fa567a23931c838c6b02d0764611c62290062a6d4e8ff7863daf9730/cffi-2.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c654de545946e0db659b3400168c9ad31b5d29593291482c43e3564effbcee13", size = 181487, upload-time = "2025-09-08T23:23:19.622Z" }, + { url = "https://files.pythonhosted.org/packages/d6/43/0e822876f87ea8a4ef95442c3d766a06a51fc5298823f884ef87aaad168c/cffi-2.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:24b6f81f1983e6df8db3adc38562c83f7d4a0c36162885ec7f7b77c7dcbec97b", size = 220049, upload-time = "2025-09-08T23:23:20.853Z" }, + { url = "https://files.pythonhosted.org/packages/b4/89/76799151d9c2d2d1ead63c2429da9ea9d7aac304603de0c6e8764e6e8e70/cffi-2.0.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:12873ca6cb9b0f0d3a0da705d6086fe911591737a59f28b7936bdfed27c0d47c", size = 207793, upload-time = "2025-09-08T23:23:22.08Z" }, + { url = "https://files.pythonhosted.org/packages/bb/dd/3465b14bb9e24ee24cb88c9e3730f6de63111fffe513492bf8c808a3547e/cffi-2.0.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:d9b97165e8aed9272a6bb17c01e3cc5871a594a446ebedc996e2397a1c1ea8ef", size = 206300, upload-time = "2025-09-08T23:23:23.314Z" }, + { url = "https://files.pythonhosted.org/packages/47/d9/d83e293854571c877a92da46fdec39158f8d7e68da75bf73581225d28e90/cffi-2.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:afb8db5439b81cf9c9d0c80404b60c3cc9c3add93e114dcae767f1477cb53775", size = 219244, upload-time = "2025-09-08T23:23:24.541Z" }, + { url = "https://files.pythonhosted.org/packages/2b/0f/1f177e3683aead2bb00f7679a16451d302c436b5cbf2505f0ea8146ef59e/cffi-2.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:737fe7d37e1a1bffe70bd5754ea763a62a066dc5913ca57e957824b72a85e205", size = 222828, upload-time = "2025-09-08T23:23:26.143Z" }, + { url = "https://files.pythonhosted.org/packages/c6/0f/cafacebd4b040e3119dcb32fed8bdef8dfe94da653155f9d0b9dc660166e/cffi-2.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:38100abb9d1b1435bc4cc340bb4489635dc2f0da7456590877030c9b3d40b0c1", size = 220926, upload-time = "2025-09-08T23:23:27.873Z" }, + { url = "https://files.pythonhosted.org/packages/3e/aa/df335faa45b395396fcbc03de2dfcab242cd61a9900e914fe682a59170b1/cffi-2.0.0-cp314-cp314-win32.whl", hash = "sha256:087067fa8953339c723661eda6b54bc98c5625757ea62e95eb4898ad5e776e9f", size = 175328, upload-time = "2025-09-08T23:23:44.61Z" }, + { url = "https://files.pythonhosted.org/packages/bb/92/882c2d30831744296ce713f0feb4c1cd30f346ef747b530b5318715cc367/cffi-2.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:203a48d1fb583fc7d78a4c6655692963b860a417c0528492a6bc21f1aaefab25", size = 185650, upload-time = "2025-09-08T23:23:45.848Z" }, + { url = "https://files.pythonhosted.org/packages/9f/2c/98ece204b9d35a7366b5b2c6539c350313ca13932143e79dc133ba757104/cffi-2.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:dbd5c7a25a7cb98f5ca55d258b103a2054f859a46ae11aaf23134f9cc0d356ad", size = 180687, upload-time = "2025-09-08T23:23:47.105Z" }, + { url = "https://files.pythonhosted.org/packages/3e/61/c768e4d548bfa607abcda77423448df8c471f25dbe64fb2ef6d555eae006/cffi-2.0.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:9a67fc9e8eb39039280526379fb3a70023d77caec1852002b4da7e8b270c4dd9", size = 188773, upload-time = "2025-09-08T23:23:29.347Z" }, + { url = "https://files.pythonhosted.org/packages/2c/ea/5f76bce7cf6fcd0ab1a1058b5af899bfbef198bea4d5686da88471ea0336/cffi-2.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7a66c7204d8869299919db4d5069a82f1561581af12b11b3c9f48c584eb8743d", size = 185013, upload-time = "2025-09-08T23:23:30.63Z" }, + { url = "https://files.pythonhosted.org/packages/be/b4/c56878d0d1755cf9caa54ba71e5d049479c52f9e4afc230f06822162ab2f/cffi-2.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7cc09976e8b56f8cebd752f7113ad07752461f48a58cbba644139015ac24954c", size = 221593, upload-time = "2025-09-08T23:23:31.91Z" }, + { url = "https://files.pythonhosted.org/packages/e0/0d/eb704606dfe8033e7128df5e90fee946bbcb64a04fcdaa97321309004000/cffi-2.0.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:92b68146a71df78564e4ef48af17551a5ddd142e5190cdf2c5624d0c3ff5b2e8", size = 209354, upload-time = "2025-09-08T23:23:33.214Z" }, + { url = "https://files.pythonhosted.org/packages/d8/19/3c435d727b368ca475fb8742ab97c9cb13a0de600ce86f62eab7fa3eea60/cffi-2.0.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b1e74d11748e7e98e2f426ab176d4ed720a64412b6a15054378afdb71e0f37dc", size = 208480, upload-time = "2025-09-08T23:23:34.495Z" }, + { url = "https://files.pythonhosted.org/packages/d0/44/681604464ed9541673e486521497406fadcc15b5217c3e326b061696899a/cffi-2.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:28a3a209b96630bca57cce802da70c266eb08c6e97e5afd61a75611ee6c64592", size = 221584, upload-time = "2025-09-08T23:23:36.096Z" }, + { url = "https://files.pythonhosted.org/packages/25/8e/342a504ff018a2825d395d44d63a767dd8ebc927ebda557fecdaca3ac33a/cffi-2.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7553fb2090d71822f02c629afe6042c299edf91ba1bf94951165613553984512", size = 224443, upload-time = "2025-09-08T23:23:37.328Z" }, + { url = "https://files.pythonhosted.org/packages/e1/5e/b666bacbbc60fbf415ba9988324a132c9a7a0448a9a8f125074671c0f2c3/cffi-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c6c373cfc5c83a975506110d17457138c8c63016b563cc9ed6e056a82f13ce4", size = 223437, upload-time = "2025-09-08T23:23:38.945Z" }, + { url = "https://files.pythonhosted.org/packages/a0/1d/ec1a60bd1a10daa292d3cd6bb0b359a81607154fb8165f3ec95fe003b85c/cffi-2.0.0-cp314-cp314t-win32.whl", hash = "sha256:1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e", size = 180487, upload-time = "2025-09-08T23:23:40.423Z" }, + { url = "https://files.pythonhosted.org/packages/bf/41/4c1168c74fac325c0c8156f04b6749c8b6a8f405bbf91413ba088359f60d/cffi-2.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6", size = 191726, upload-time = "2025-09-08T23:23:41.742Z" }, + { url = "https://files.pythonhosted.org/packages/ae/3a/dbeec9d1ee0844c679f6bb5d6ad4e9f198b1224f4e7a32825f47f6192b0c/cffi-2.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9", size = 184195, upload-time = "2025-09-08T23:23:43.004Z" }, +] + [[package]] name = "colorama" version = "0.4.6" @@ -19,11 +82,21 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, ] +[[package]] +name = "comm" +version = "0.2.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4c/13/7d740c5849255756bc17888787313b61fd38a0a8304fc4f073dfc46122aa/comm-0.2.3.tar.gz", hash = "sha256:2dc8048c10962d55d7ad693be1e7045d891b7ce8d999c97963a5e3e99c055971", size = 6319, upload-time = "2025-07-25T14:02:04.452Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/60/97/891a0971e1e4a8c5d2b20bbe0e524dc04548d2307fee33cdeba148fd4fc7/comm-0.2.3-py3-none-any.whl", hash = "sha256:c615d91d75f7f04f095b30d1c1711babd43bdc6419c1be9886a85f2f4e489417", size = 7294, upload-time = "2025-07-25T14:02:02.896Z" }, +] + [[package]] name = "dataclean-workshop" version = "0.1.0" source = { virtual = "." } dependencies = [ + { name = "ipykernel" }, { name = "pandas" }, { name = "scikit-learn" }, ] @@ -35,6 +108,7 @@ dev = [ [package.metadata] requires-dist = [ + { name = "ipykernel", specifier = ">=7.2.0" }, { name = "pandas", specifier = ">=3.0.2" }, { name = "scikit-learn", specifier = ">=1.7.2" }, ] @@ -42,6 +116,41 @@ requires-dist = [ [package.metadata.requires-dev] dev = [{ name = "pytest", specifier = ">=8.4.2" }] +[[package]] +name = "debugpy" +version = "1.8.20" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e0/b7/cd8080344452e4874aae67c40d8940e2b4d47b01601a8fd9f44786c757c7/debugpy-1.8.20.tar.gz", hash = "sha256:55bc8701714969f1ab89a6d5f2f3d40c36f91b2cbe2f65d98bf8196f6a6a2c33", size = 1645207, upload-time = "2026-01-29T23:03:28.199Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/15/e2/fc500524cc6f104a9d049abc85a0a8b3f0d14c0a39b9c140511c61e5b40b/debugpy-1.8.20-cp313-cp313-macosx_15_0_universal2.whl", hash = "sha256:5dff4bb27027821fdfcc9e8f87309a28988231165147c31730128b1c983e282a", size = 2539560, upload-time = "2026-01-29T23:03:48.738Z" }, + { url = "https://files.pythonhosted.org/packages/90/83/fb33dcea789ed6018f8da20c5a9bc9d82adc65c0c990faed43f7c955da46/debugpy-1.8.20-cp313-cp313-manylinux_2_34_x86_64.whl", hash = "sha256:84562982dd7cf5ebebfdea667ca20a064e096099997b175fe204e86817f64eaf", size = 4293272, upload-time = "2026-01-29T23:03:50.169Z" }, + { url = "https://files.pythonhosted.org/packages/a6/25/b1e4a01bfb824d79a6af24b99ef291e24189080c93576dfd9b1a2815cd0f/debugpy-1.8.20-cp313-cp313-win32.whl", hash = "sha256:da11dea6447b2cadbf8ce2bec59ecea87cc18d2c574980f643f2d2dfe4862393", size = 5331208, upload-time = "2026-01-29T23:03:51.547Z" }, + { url = "https://files.pythonhosted.org/packages/13/f7/a0b368ce54ffff9e9028c098bd2d28cfc5b54f9f6c186929083d4c60ba58/debugpy-1.8.20-cp313-cp313-win_amd64.whl", hash = "sha256:eb506e45943cab2efb7c6eafdd65b842f3ae779f020c82221f55aca9de135ed7", size = 5372930, upload-time = "2026-01-29T23:03:53.585Z" }, + { url = "https://files.pythonhosted.org/packages/33/2e/f6cb9a8a13f5058f0a20fe09711a7b726232cd5a78c6a7c05b2ec726cff9/debugpy-1.8.20-cp314-cp314-macosx_15_0_universal2.whl", hash = "sha256:9c74df62fc064cd5e5eaca1353a3ef5a5d50da5eb8058fcef63106f7bebe6173", size = 2538066, upload-time = "2026-01-29T23:03:54.999Z" }, + { url = "https://files.pythonhosted.org/packages/c5/56/6ddca50b53624e1ca3ce1d1e49ff22db46c47ea5fb4c0cc5c9b90a616364/debugpy-1.8.20-cp314-cp314-manylinux_2_34_x86_64.whl", hash = "sha256:077a7447589ee9bc1ff0cdf443566d0ecf540ac8aa7333b775ebcb8ce9f4ecad", size = 4269425, upload-time = "2026-01-29T23:03:56.518Z" }, + { url = "https://files.pythonhosted.org/packages/c5/d9/d64199c14a0d4c476df46c82470a3ce45c8d183a6796cfb5e66533b3663c/debugpy-1.8.20-cp314-cp314-win32.whl", hash = "sha256:352036a99dd35053b37b7803f748efc456076f929c6a895556932eaf2d23b07f", size = 5331407, upload-time = "2026-01-29T23:03:58.481Z" }, + { url = "https://files.pythonhosted.org/packages/e0/d9/1f07395b54413432624d61524dfd98c1a7c7827d2abfdb8829ac92638205/debugpy-1.8.20-cp314-cp314-win_amd64.whl", hash = "sha256:a98eec61135465b062846112e5ecf2eebb855305acc1dfbae43b72903b8ab5be", size = 5372521, upload-time = "2026-01-29T23:03:59.864Z" }, + { url = "https://files.pythonhosted.org/packages/e0/c3/7f67dea8ccf8fdcb9c99033bbe3e90b9e7395415843accb81428c441be2d/debugpy-1.8.20-py2.py3-none-any.whl", hash = "sha256:5be9bed9ae3be00665a06acaa48f8329d2b9632f15fd09f6a9a8c8d9907e54d7", size = 5337658, upload-time = "2026-01-29T23:04:17.404Z" }, +] + +[[package]] +name = "decorator" +version = "5.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/60/8b/32f9823da46cde7df2087faa08cd98d01b908f8dcab982cdba9c84e85355/decorator-5.3.1.tar.gz", hash = "sha256:4cbcdd55a6efadb9dbea26b858f4fb3264567b52d69ca0d25b721b553f60ea82", size = 58084, upload-time = "2026-05-18T06:03:28.057Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/05/7f/798705f5296a58ca505d600456748d1be48078eac8a7050d8a98bc9edb89/decorator-5.3.1-py3-none-any.whl", hash = "sha256:f47fe6fdbd2edd623ecfe36875d37aba411624e2670dd395dddae1358689bb3c", size = 10365, upload-time = "2026-05-18T06:03:26.517Z" }, +] + +[[package]] +name = "executing" +version = "2.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cc/28/c14e053b6762b1044f34a13aab6859bbf40456d37d23aa286ac24cfd9a5d/executing-2.2.1.tar.gz", hash = "sha256:3632cc370565f6648cc328b32435bd120a1e4ebb20c77e3fdde9a13cd1e533c4", size = 1129488, upload-time = "2025-09-01T09:48:10.866Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c1/ea/53f2148663b321f21b5a606bd5f191517cf40b7072c0497d3c92c4a13b1e/executing-2.2.1-py2.py3-none-any.whl", hash = "sha256:760643d3452b4d777d295bb167ccc74c64a81df23fb5e08eff250c425a4b2017", size = 28317, upload-time = "2025-09-01T09:48:08.5Z" }, +] + [[package]] name = "iniconfig" version = "2.3.0" @@ -51,6 +160,76 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, ] +[[package]] +name = "ipykernel" +version = "7.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "appnope", marker = "sys_platform == 'darwin'" }, + { name = "comm" }, + { name = "debugpy" }, + { name = "ipython" }, + { name = "jupyter-client" }, + { name = "jupyter-core" }, + { name = "matplotlib-inline" }, + { name = "nest-asyncio" }, + { name = "packaging" }, + { name = "psutil" }, + { name = "pyzmq" }, + { name = "tornado" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ca/8d/b68b728e2d06b9e0051019640a40a9eb7a88fcd82c2e1b5ce70bef5ff044/ipykernel-7.2.0.tar.gz", hash = "sha256:18ed160b6dee2cbb16e5f3575858bc19d8f1fe6046a9a680c708494ce31d909e", size = 176046, upload-time = "2026-02-06T16:43:27.403Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/82/b9/e73d5d9f405cba7706c539aa8b311b49d4c2f3d698d9c12f815231169c71/ipykernel-7.2.0-py3-none-any.whl", hash = "sha256:3bbd4420d2b3cc105cbdf3756bfc04500b1e52f090a90716851f3916c62e1661", size = 118788, upload-time = "2026-02-06T16:43:25.149Z" }, +] + +[[package]] +name = "ipython" +version = "9.14.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "decorator" }, + { name = "ipython-pygments-lexers" }, + { name = "jedi" }, + { name = "matplotlib-inline" }, + { name = "pexpect", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" }, + { name = "prompt-toolkit" }, + { name = "psutil", marker = "sys_platform != 'emscripten'" }, + { name = "pygments" }, + { name = "stack-data" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/21/c2/c0064cf15d026501a1ef70e42efd9c3f818663089399aacc5e37a82901c1/ipython-9.14.0.tar.gz", hash = "sha256:6f27ff0f1d9ea050e0551f71568bc4b34d8aba579e8f111c5b4175f44ac6b4aa", size = 4432601, upload-time = "2026-05-29T15:13:24.611Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/14/a3/9e59340f02c1dc8f8c0a05b09244712b8609eb5439f9996e887e2b82f452/ipython-9.14.0-py3-none-any.whl", hash = "sha256:8fd984a3372c14b12790b084ba6b5cff5678c0cb063244a0034f06a51f20d6c2", size = 627457, upload-time = "2026-05-29T15:13:22.942Z" }, +] + +[[package]] +name = "ipython-pygments-lexers" +version = "1.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ef/4c/5dd1d8af08107f88c7f741ead7a40854b8ac24ddf9ae850afbcf698aa552/ipython_pygments_lexers-1.1.1.tar.gz", hash = "sha256:09c0138009e56b6854f9535736f4171d855c8c08a563a0dcd8022f78355c7e81", size = 8393, upload-time = "2025-01-17T11:24:34.505Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d9/33/1f075bf72b0b747cb3288d011319aaf64083cf2efef8354174e3ed4540e2/ipython_pygments_lexers-1.1.1-py3-none-any.whl", hash = "sha256:a9462224a505ade19a605f71f8fa63c2048833ce50abc86768a0d81d876dc81c", size = 8074, upload-time = "2025-01-17T11:24:33.271Z" }, +] + +[[package]] +name = "jedi" +version = "0.20.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "parso" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/46/b7/a3635f6a2d7cf5b5dd98064fc1d5fbbafcb25477bcea204a3a92145d158b/jedi-0.20.0.tar.gz", hash = "sha256:c3f4ccbd276696f4b19c54618d4fb18f9fc24b0aef02acf704b23f487daa1011", size = 3119416, upload-time = "2026-05-01T23:38:47.814Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9a/93/242e2eab5fe682ffcb8b0084bde703a41d51e17ee0f3a31ff0d9d813620a/jedi-0.20.0-py2.py3-none-any.whl", hash = "sha256:7bdd9c2634f56713299976f4cbd59cb3fa92165cc5e05ea811fb253480728b67", size = 4884812, upload-time = "2026-05-01T23:38:43.919Z" }, +] + [[package]] name = "joblib" version = "1.5.3" @@ -60,6 +239,56 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7b/91/984aca2ec129e2757d1e4e3c81c3fcda9d0f85b74670a094cc443d9ee949/joblib-1.5.3-py3-none-any.whl", hash = "sha256:5fc3c5039fc5ca8c0276333a188bbd59d6b7ab37fe6632daa76bc7f9ec18e713", size = 309071, upload-time = "2025-12-15T08:41:44.973Z" }, ] +[[package]] +name = "jupyter-client" +version = "8.8.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-core" }, + { name = "python-dateutil" }, + { name = "pyzmq" }, + { name = "tornado" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/05/e4/ba649102a3bc3fbca54e7239fb924fd434c766f855693d86de0b1f2bec81/jupyter_client-8.8.0.tar.gz", hash = "sha256:d556811419a4f2d96c869af34e854e3f059b7cc2d6d01a9cd9c85c267691be3e", size = 348020, upload-time = "2026-01-08T13:55:47.938Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2d/0b/ceb7694d864abc0a047649aec263878acb9f792e1fec3e676f22dc9015e3/jupyter_client-8.8.0-py3-none-any.whl", hash = "sha256:f93a5b99c5e23a507b773d3a1136bd6e16c67883ccdbd9a829b0bbdb98cd7d7a", size = 107371, upload-time = "2026-01-08T13:55:45.562Z" }, +] + +[[package]] +name = "jupyter-core" +version = "5.9.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "platformdirs" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/02/49/9d1284d0dc65e2c757b74c6687b6d319b02f822ad039e5c512df9194d9dd/jupyter_core-5.9.1.tar.gz", hash = "sha256:4d09aaff303b9566c3ce657f580bd089ff5c91f5f89cf7d8846c3cdf465b5508", size = 89814, upload-time = "2025-10-16T19:19:18.444Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/e7/80988e32bf6f73919a113473a604f5a8f09094de312b9d52b79c2df7612b/jupyter_core-5.9.1-py3-none-any.whl", hash = "sha256:ebf87fdc6073d142e114c72c9e29a9d7ca03fad818c5d300ce2adc1fb0743407", size = 29032, upload-time = "2025-10-16T19:19:16.783Z" }, +] + +[[package]] +name = "matplotlib-inline" +version = "0.2.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/bd/c0/9f7c9a46090390368a4d7bcb76bb87a4a36c421e4c0792cdb53486ffac7a/matplotlib_inline-0.2.2.tar.gz", hash = "sha256:72f3fe8fce36b70d4a5b612f899090cd0401deddc4ea90e1572b9f4bfb058c79", size = 8150, upload-time = "2026-05-08T17:33:33.49Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/41/09/5b161152e2d90f7b87f781c2e1267494aef9c32498df793f73ad0a0a494a/matplotlib_inline-0.2.2-py3-none-any.whl", hash = "sha256:3c821cf1c209f59fb2d2d64abbf5b23b67bcb2210d663f9918dd851c6da1fcf6", size = 9534, upload-time = "2026-05-08T17:33:32.055Z" }, +] + +[[package]] +name = "nest-asyncio" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/83/f8/51569ac65d696c8ecbee95938f89d4abf00f47d58d48f6fbabfe8f0baefe/nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe", size = 7418, upload-time = "2024-01-21T14:25:19.227Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c", size = 5195, upload-time = "2024-01-21T14:25:17.223Z" }, +] + [[package]] name = "numpy" version = "2.4.4" @@ -163,6 +392,36 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/cb/2b/f8434233fab2bd66a02ec014febe4e5adced20e2693e0e90a07d118ed30e/pandas-3.0.2-cp314-cp314t-win_arm64.whl", hash = "sha256:5371b72c2d4d415d08765f32d689217a43227484e81b2305b52076e328f6f482", size = 9455341, upload-time = "2026-03-31T06:48:28.418Z" }, ] +[[package]] +name = "parso" +version = "0.8.7" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/30/4b/90c937815137d43ce71ba043cd3566221e9df6b9c805f24b5d138c9d40a7/parso-0.8.7.tar.gz", hash = "sha256:eaaac4c9fdd5e9e8852dc778d2d7405897ec510f2a298071453e5e3a07914bb1", size = 401824, upload-time = "2026-05-01T23:13:02.138Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/99/5d/8268b644392ee874ee82a635cd0df1773de230bde356c38de28e298392cc/parso-0.8.7-py2.py3-none-any.whl", hash = "sha256:a8926eb2a1b915486941fdbd31e86a4baf88fe8c210f25f2f35ecec5b574ca1c", size = 107025, upload-time = "2026-05-01T23:12:58.867Z" }, +] + +[[package]] +name = "pexpect" +version = "4.9.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ptyprocess", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/42/92/cc564bf6381ff43ce1f4d06852fc19a2f11d180f23dc32d9588bee2f149d/pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f", size = 166450, upload-time = "2023-11-25T09:07:26.339Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523", size = 63772, upload-time = "2023-11-25T06:56:14.81Z" }, +] + +[[package]] +name = "platformdirs" +version = "4.10.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/47/e4501f49c178ae1d9f4a75073fda4204f52647993f075a9db4d14930e0c5/platformdirs-4.10.0.tar.gz", hash = "sha256:31e761a6a0ca04faf7353ea759bdba55652be214725111e5aac52dfa29d4bef7", size = 31224, upload-time = "2026-05-28T03:32:53.587Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/81/e6/cd9575ac904136b3cbf7aa7ee819ef86eedb7274e46f230e94ea4342e729/platformdirs-4.10.0-py3-none-any.whl", hash = "sha256:fb516cdb12eb0d857d0cd85a7c57cea4d060bee4578d6cf5a14dfdf8cbf8784a", size = 22743, upload-time = "2026-05-28T03:32:52.175Z" }, +] + [[package]] name = "pluggy" version = "1.6.0" @@ -172,6 +431,73 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, ] +[[package]] +name = "prompt-toolkit" +version = "3.0.52" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "wcwidth" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a1/96/06e01a7b38dce6fe1db213e061a4602dd6032a8a97ef6c1a862537732421/prompt_toolkit-3.0.52.tar.gz", hash = "sha256:28cde192929c8e7321de85de1ddbe736f1375148b02f2e17edd840042b1be855", size = 434198, upload-time = "2025-08-27T15:24:02.057Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl", hash = "sha256:9aac639a3bbd33284347de5ad8d68ecc044b91a762dc39b7c21095fcd6a19955", size = 391431, upload-time = "2025-08-27T15:23:59.498Z" }, +] + +[[package]] +name = "psutil" +version = "7.2.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/aa/c6/d1ddf4abb55e93cebc4f2ed8b5d6dbad109ecb8d63748dd2b20ab5e57ebe/psutil-7.2.2.tar.gz", hash = "sha256:0746f5f8d406af344fd547f1c8daa5f5c33dbc293bb8d6a16d80b4bb88f59372", size = 493740, upload-time = "2026-01-28T18:14:54.428Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/51/08/510cbdb69c25a96f4ae523f733cdc963ae654904e8db864c07585ef99875/psutil-7.2.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2edccc433cbfa046b980b0df0171cd25bcaeb3a68fe9022db0979e7aa74a826b", size = 130595, upload-time = "2026-01-28T18:14:57.293Z" }, + { url = "https://files.pythonhosted.org/packages/d6/f5/97baea3fe7a5a9af7436301f85490905379b1c6f2dd51fe3ecf24b4c5fbf/psutil-7.2.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e78c8603dcd9a04c7364f1a3e670cea95d51ee865e4efb3556a3a63adef958ea", size = 131082, upload-time = "2026-01-28T18:14:59.732Z" }, + { url = "https://files.pythonhosted.org/packages/37/d6/246513fbf9fa174af531f28412297dd05241d97a75911ac8febefa1a53c6/psutil-7.2.2-cp313-cp313t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1a571f2330c966c62aeda00dd24620425d4b0cc86881c89861fbc04549e5dc63", size = 181476, upload-time = "2026-01-28T18:15:01.884Z" }, + { url = "https://files.pythonhosted.org/packages/b8/b5/9182c9af3836cca61696dabe4fd1304e17bc56cb62f17439e1154f225dd3/psutil-7.2.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:917e891983ca3c1887b4ef36447b1e0873e70c933afc831c6b6da078ba474312", size = 184062, upload-time = "2026-01-28T18:15:04.436Z" }, + { url = "https://files.pythonhosted.org/packages/16/ba/0756dca669f5a9300d0cbcbfae9a4c30e446dfc7440ffe43ded5724bfd93/psutil-7.2.2-cp313-cp313t-win_amd64.whl", hash = "sha256:ab486563df44c17f5173621c7b198955bd6b613fb87c71c161f827d3fb149a9b", size = 139893, upload-time = "2026-01-28T18:15:06.378Z" }, + { url = "https://files.pythonhosted.org/packages/1c/61/8fa0e26f33623b49949346de05ec1ddaad02ed8ba64af45f40a147dbfa97/psutil-7.2.2-cp313-cp313t-win_arm64.whl", hash = "sha256:ae0aefdd8796a7737eccea863f80f81e468a1e4cf14d926bd9b6f5f2d5f90ca9", size = 135589, upload-time = "2026-01-28T18:15:08.03Z" }, + { url = "https://files.pythonhosted.org/packages/81/69/ef179ab5ca24f32acc1dac0c247fd6a13b501fd5534dbae0e05a1c48b66d/psutil-7.2.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:eed63d3b4d62449571547b60578c5b2c4bcccc5387148db46e0c2313dad0ee00", size = 130664, upload-time = "2026-01-28T18:15:09.469Z" }, + { url = "https://files.pythonhosted.org/packages/7b/64/665248b557a236d3fa9efc378d60d95ef56dd0a490c2cd37dafc7660d4a9/psutil-7.2.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7b6d09433a10592ce39b13d7be5a54fbac1d1228ed29abc880fb23df7cb694c9", size = 131087, upload-time = "2026-01-28T18:15:11.724Z" }, + { url = "https://files.pythonhosted.org/packages/d5/2e/e6782744700d6759ebce3043dcfa661fb61e2fb752b91cdeae9af12c2178/psutil-7.2.2-cp314-cp314t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1fa4ecf83bcdf6e6c8f4449aff98eefb5d0604bf88cb883d7da3d8d2d909546a", size = 182383, upload-time = "2026-01-28T18:15:13.445Z" }, + { url = "https://files.pythonhosted.org/packages/57/49/0a41cefd10cb7505cdc04dab3eacf24c0c2cb158a998b8c7b1d27ee2c1f5/psutil-7.2.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e452c464a02e7dc7822a05d25db4cde564444a67e58539a00f929c51eddda0cf", size = 185210, upload-time = "2026-01-28T18:15:16.002Z" }, + { url = "https://files.pythonhosted.org/packages/dd/2c/ff9bfb544f283ba5f83ba725a3c5fec6d6b10b8f27ac1dc641c473dc390d/psutil-7.2.2-cp314-cp314t-win_amd64.whl", hash = "sha256:c7663d4e37f13e884d13994247449e9f8f574bc4655d509c3b95e9ec9e2b9dc1", size = 141228, upload-time = "2026-01-28T18:15:18.385Z" }, + { url = "https://files.pythonhosted.org/packages/f2/fc/f8d9c31db14fcec13748d373e668bc3bed94d9077dbc17fb0eebc073233c/psutil-7.2.2-cp314-cp314t-win_arm64.whl", hash = "sha256:11fe5a4f613759764e79c65cf11ebdf26e33d6dd34336f8a337aa2996d71c841", size = 136284, upload-time = "2026-01-28T18:15:19.912Z" }, + { url = "https://files.pythonhosted.org/packages/e7/36/5ee6e05c9bd427237b11b3937ad82bb8ad2752d72c6969314590dd0c2f6e/psutil-7.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ed0cace939114f62738d808fdcecd4c869222507e266e574799e9c0faa17d486", size = 129090, upload-time = "2026-01-28T18:15:22.168Z" }, + { url = "https://files.pythonhosted.org/packages/80/c4/f5af4c1ca8c1eeb2e92ccca14ce8effdeec651d5ab6053c589b074eda6e1/psutil-7.2.2-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:1a7b04c10f32cc88ab39cbf606e117fd74721c831c98a27dc04578deb0c16979", size = 129859, upload-time = "2026-01-28T18:15:23.795Z" }, + { url = "https://files.pythonhosted.org/packages/b5/70/5d8df3b09e25bce090399cf48e452d25c935ab72dad19406c77f4e828045/psutil-7.2.2-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:076a2d2f923fd4821644f5ba89f059523da90dc9014e85f8e45a5774ca5bc6f9", size = 155560, upload-time = "2026-01-28T18:15:25.976Z" }, + { url = "https://files.pythonhosted.org/packages/63/65/37648c0c158dc222aba51c089eb3bdfa238e621674dc42d48706e639204f/psutil-7.2.2-cp36-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b0726cecd84f9474419d67252add4ac0cd9811b04d61123054b9fb6f57df6e9e", size = 156997, upload-time = "2026-01-28T18:15:27.794Z" }, + { url = "https://files.pythonhosted.org/packages/8e/13/125093eadae863ce03c6ffdbae9929430d116a246ef69866dad94da3bfbc/psutil-7.2.2-cp36-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:fd04ef36b4a6d599bbdb225dd1d3f51e00105f6d48a28f006da7f9822f2606d8", size = 148972, upload-time = "2026-01-28T18:15:29.342Z" }, + { url = "https://files.pythonhosted.org/packages/04/78/0acd37ca84ce3ddffaa92ef0f571e073faa6d8ff1f0559ab1272188ea2be/psutil-7.2.2-cp36-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b58fabe35e80b264a4e3bb23e6b96f9e45a3df7fb7eed419ac0e5947c61e47cc", size = 148266, upload-time = "2026-01-28T18:15:31.597Z" }, + { url = "https://files.pythonhosted.org/packages/b4/90/e2159492b5426be0c1fef7acba807a03511f97c5f86b3caeda6ad92351a7/psutil-7.2.2-cp37-abi3-win_amd64.whl", hash = "sha256:eb7e81434c8d223ec4a219b5fc1c47d0417b12be7ea866e24fb5ad6e84b3d988", size = 137737, upload-time = "2026-01-28T18:15:33.849Z" }, + { url = "https://files.pythonhosted.org/packages/8c/c7/7bb2e321574b10df20cbde462a94e2b71d05f9bbda251ef27d104668306a/psutil-7.2.2-cp37-abi3-win_arm64.whl", hash = "sha256:8c233660f575a5a89e6d4cb65d9f938126312bca76d8fe087b947b3a1aaac9ee", size = 134617, upload-time = "2026-01-28T18:15:36.514Z" }, +] + +[[package]] +name = "ptyprocess" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/20/e5/16ff212c1e452235a90aeb09066144d0c5a6a8c0834397e03f5224495c4e/ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220", size = 70762, upload-time = "2020-12-28T15:15:30.155Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35", size = 13993, upload-time = "2020-12-28T15:15:28.35Z" }, +] + +[[package]] +name = "pure-eval" +version = "0.2.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cd/05/0a34433a064256a578f1783a10da6df098ceaa4a57bbeaa96a6c0352786b/pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42", size = 19752, upload-time = "2024-07-21T12:58:21.801Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0", size = 11842, upload-time = "2024-07-21T12:58:20.04Z" }, +] + +[[package]] +name = "pycparser" +version = "3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1b/7d/92392ff7815c21062bea51aa7b87d45576f649f16458d78b7cf94b9ab2e6/pycparser-3.0.tar.gz", hash = "sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29", size = 103492, upload-time = "2026-01-21T14:26:51.89Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl", hash = "sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992", size = 48172, upload-time = "2026-01-21T14:26:50.693Z" }, +] + [[package]] name = "pygments" version = "2.20.0" @@ -209,6 +535,49 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, ] +[[package]] +name = "pyzmq" +version = "27.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi", marker = "implementation_name == 'pypy'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/04/0b/3c9baedbdf613ecaa7aa07027780b8867f57b6293b6ee50de316c9f3222b/pyzmq-27.1.0.tar.gz", hash = "sha256:ac0765e3d44455adb6ddbf4417dcce460fc40a05978c08efdf2948072f6db540", size = 281750, upload-time = "2025-09-08T23:10:18.157Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/92/e7/038aab64a946d535901103da16b953c8c9cc9c961dadcbf3609ed6428d23/pyzmq-27.1.0-cp312-abi3-macosx_10_15_universal2.whl", hash = "sha256:452631b640340c928fa343801b0d07eb0c3789a5ffa843f6e1a9cee0ba4eb4fc", size = 1306279, upload-time = "2025-09-08T23:08:03.807Z" }, + { url = "https://files.pythonhosted.org/packages/e8/5e/c3c49fdd0f535ef45eefcc16934648e9e59dace4a37ee88fc53f6cd8e641/pyzmq-27.1.0-cp312-abi3-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:1c179799b118e554b66da67d88ed66cd37a169f1f23b5d9f0a231b4e8d44a113", size = 895645, upload-time = "2025-09-08T23:08:05.301Z" }, + { url = "https://files.pythonhosted.org/packages/f8/e5/b0b2504cb4e903a74dcf1ebae157f9e20ebb6ea76095f6cfffea28c42ecd/pyzmq-27.1.0-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3837439b7f99e60312f0c926a6ad437b067356dc2bc2ec96eb395fd0fe804233", size = 652574, upload-time = "2025-09-08T23:08:06.828Z" }, + { url = "https://files.pythonhosted.org/packages/f8/9b/c108cdb55560eaf253f0cbdb61b29971e9fb34d9c3499b0e96e4e60ed8a5/pyzmq-27.1.0-cp312-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:43ad9a73e3da1fab5b0e7e13402f0b2fb934ae1c876c51d0afff0e7c052eca31", size = 840995, upload-time = "2025-09-08T23:08:08.396Z" }, + { url = "https://files.pythonhosted.org/packages/c2/bb/b79798ca177b9eb0825b4c9998c6af8cd2a7f15a6a1a4272c1d1a21d382f/pyzmq-27.1.0-cp312-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:0de3028d69d4cdc475bfe47a6128eb38d8bc0e8f4d69646adfbcd840facbac28", size = 1642070, upload-time = "2025-09-08T23:08:09.989Z" }, + { url = "https://files.pythonhosted.org/packages/9c/80/2df2e7977c4ede24c79ae39dcef3899bfc5f34d1ca7a5b24f182c9b7a9ca/pyzmq-27.1.0-cp312-abi3-musllinux_1_2_i686.whl", hash = "sha256:cf44a7763aea9298c0aa7dbf859f87ed7012de8bda0f3977b6fb1d96745df856", size = 2021121, upload-time = "2025-09-08T23:08:11.907Z" }, + { url = "https://files.pythonhosted.org/packages/46/bd/2d45ad24f5f5ae7e8d01525eb76786fa7557136555cac7d929880519e33a/pyzmq-27.1.0-cp312-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:f30f395a9e6fbca195400ce833c731e7b64c3919aa481af4d88c3759e0cb7496", size = 1878550, upload-time = "2025-09-08T23:08:13.513Z" }, + { url = "https://files.pythonhosted.org/packages/e6/2f/104c0a3c778d7c2ab8190e9db4f62f0b6957b53c9d87db77c284b69f33ea/pyzmq-27.1.0-cp312-abi3-win32.whl", hash = "sha256:250e5436a4ba13885494412b3da5d518cd0d3a278a1ae640e113c073a5f88edd", size = 559184, upload-time = "2025-09-08T23:08:15.163Z" }, + { url = "https://files.pythonhosted.org/packages/fc/7f/a21b20d577e4100c6a41795842028235998a643b1ad406a6d4163ea8f53e/pyzmq-27.1.0-cp312-abi3-win_amd64.whl", hash = "sha256:9ce490cf1d2ca2ad84733aa1d69ce6855372cb5ce9223802450c9b2a7cba0ccf", size = 619480, upload-time = "2025-09-08T23:08:17.192Z" }, + { url = "https://files.pythonhosted.org/packages/78/c2/c012beae5f76b72f007a9e91ee9401cb88c51d0f83c6257a03e785c81cc2/pyzmq-27.1.0-cp312-abi3-win_arm64.whl", hash = "sha256:75a2f36223f0d535a0c919e23615fc85a1e23b71f40c7eb43d7b1dedb4d8f15f", size = 552993, upload-time = "2025-09-08T23:08:18.926Z" }, + { url = "https://files.pythonhosted.org/packages/60/cb/84a13459c51da6cec1b7b1dc1a47e6db6da50b77ad7fd9c145842750a011/pyzmq-27.1.0-cp313-cp313-android_24_arm64_v8a.whl", hash = "sha256:93ad4b0855a664229559e45c8d23797ceac03183c7b6f5b4428152a6b06684a5", size = 1122436, upload-time = "2025-09-08T23:08:20.801Z" }, + { url = "https://files.pythonhosted.org/packages/dc/b6/94414759a69a26c3dd674570a81813c46a078767d931a6c70ad29fc585cb/pyzmq-27.1.0-cp313-cp313-android_24_x86_64.whl", hash = "sha256:fbb4f2400bfda24f12f009cba62ad5734148569ff4949b1b6ec3b519444342e6", size = 1156301, upload-time = "2025-09-08T23:08:22.47Z" }, + { url = "https://files.pythonhosted.org/packages/a5/ad/15906493fd40c316377fd8a8f6b1f93104f97a752667763c9b9c1b71d42d/pyzmq-27.1.0-cp313-cp313t-macosx_10_15_universal2.whl", hash = "sha256:e343d067f7b151cfe4eb3bb796a7752c9d369eed007b91231e817071d2c2fec7", size = 1341197, upload-time = "2025-09-08T23:08:24.286Z" }, + { url = "https://files.pythonhosted.org/packages/14/1d/d343f3ce13db53a54cb8946594e567410b2125394dafcc0268d8dda027e0/pyzmq-27.1.0-cp313-cp313t-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:08363b2011dec81c354d694bdecaef4770e0ae96b9afea70b3f47b973655cc05", size = 897275, upload-time = "2025-09-08T23:08:26.063Z" }, + { url = "https://files.pythonhosted.org/packages/69/2d/d83dd6d7ca929a2fc67d2c3005415cdf322af7751d773524809f9e585129/pyzmq-27.1.0-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d54530c8c8b5b8ddb3318f481297441af102517602b569146185fa10b63f4fa9", size = 660469, upload-time = "2025-09-08T23:08:27.623Z" }, + { url = "https://files.pythonhosted.org/packages/3e/cd/9822a7af117f4bc0f1952dbe9ef8358eb50a24928efd5edf54210b850259/pyzmq-27.1.0-cp313-cp313t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6f3afa12c392f0a44a2414056d730eebc33ec0926aae92b5ad5cf26ebb6cc128", size = 847961, upload-time = "2025-09-08T23:08:29.672Z" }, + { url = "https://files.pythonhosted.org/packages/9a/12/f003e824a19ed73be15542f172fd0ec4ad0b60cf37436652c93b9df7c585/pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:c65047adafe573ff023b3187bb93faa583151627bc9c51fc4fb2c561ed689d39", size = 1650282, upload-time = "2025-09-08T23:08:31.349Z" }, + { url = "https://files.pythonhosted.org/packages/d5/4a/e82d788ed58e9a23995cee70dbc20c9aded3d13a92d30d57ec2291f1e8a3/pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:90e6e9441c946a8b0a667356f7078d96411391a3b8f80980315455574177ec97", size = 2024468, upload-time = "2025-09-08T23:08:33.543Z" }, + { url = "https://files.pythonhosted.org/packages/d9/94/2da0a60841f757481e402b34bf4c8bf57fa54a5466b965de791b1e6f747d/pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:add071b2d25f84e8189aaf0882d39a285b42fa3853016ebab234a5e78c7a43db", size = 1885394, upload-time = "2025-09-08T23:08:35.51Z" }, + { url = "https://files.pythonhosted.org/packages/4f/6f/55c10e2e49ad52d080dc24e37adb215e5b0d64990b57598abc2e3f01725b/pyzmq-27.1.0-cp313-cp313t-win32.whl", hash = "sha256:7ccc0700cfdf7bd487bea8d850ec38f204478681ea02a582a8da8171b7f90a1c", size = 574964, upload-time = "2025-09-08T23:08:37.178Z" }, + { url = "https://files.pythonhosted.org/packages/87/4d/2534970ba63dd7c522d8ca80fb92777f362c0f321900667c615e2067cb29/pyzmq-27.1.0-cp313-cp313t-win_amd64.whl", hash = "sha256:8085a9fba668216b9b4323be338ee5437a235fe275b9d1610e422ccc279733e2", size = 641029, upload-time = "2025-09-08T23:08:40.595Z" }, + { url = "https://files.pythonhosted.org/packages/f6/fa/f8aea7a28b0641f31d40dea42d7ef003fded31e184ef47db696bc74cd610/pyzmq-27.1.0-cp313-cp313t-win_arm64.whl", hash = "sha256:6bb54ca21bcfe361e445256c15eedf083f153811c37be87e0514934d6913061e", size = 561541, upload-time = "2025-09-08T23:08:42.668Z" }, + { url = "https://files.pythonhosted.org/packages/87/45/19efbb3000956e82d0331bafca5d9ac19ea2857722fa2caacefb6042f39d/pyzmq-27.1.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:ce980af330231615756acd5154f29813d553ea555485ae712c491cd483df6b7a", size = 1341197, upload-time = "2025-09-08T23:08:44.973Z" }, + { url = "https://files.pythonhosted.org/packages/48/43/d72ccdbf0d73d1343936296665826350cb1e825f92f2db9db3e61c2162a2/pyzmq-27.1.0-cp314-cp314t-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:1779be8c549e54a1c38f805e56d2a2e5c009d26de10921d7d51cfd1c8d4632ea", size = 897175, upload-time = "2025-09-08T23:08:46.601Z" }, + { url = "https://files.pythonhosted.org/packages/2f/2e/a483f73a10b65a9ef0161e817321d39a770b2acf8bcf3004a28d90d14a94/pyzmq-27.1.0-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7200bb0f03345515df50d99d3db206a0a6bee1955fbb8c453c76f5bf0e08fb96", size = 660427, upload-time = "2025-09-08T23:08:48.187Z" }, + { url = "https://files.pythonhosted.org/packages/f5/d2/5f36552c2d3e5685abe60dfa56f91169f7a2d99bbaf67c5271022ab40863/pyzmq-27.1.0-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01c0e07d558b06a60773744ea6251f769cd79a41a97d11b8bf4ab8f034b0424d", size = 847929, upload-time = "2025-09-08T23:08:49.76Z" }, + { url = "https://files.pythonhosted.org/packages/c4/2a/404b331f2b7bf3198e9945f75c4c521f0c6a3a23b51f7a4a401b94a13833/pyzmq-27.1.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:80d834abee71f65253c91540445d37c4c561e293ba6e741b992f20a105d69146", size = 1650193, upload-time = "2025-09-08T23:08:51.7Z" }, + { url = "https://files.pythonhosted.org/packages/1c/0b/f4107e33f62a5acf60e3ded67ed33d79b4ce18de432625ce2fc5093d6388/pyzmq-27.1.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:544b4e3b7198dde4a62b8ff6685e9802a9a1ebf47e77478a5eb88eca2a82f2fd", size = 2024388, upload-time = "2025-09-08T23:08:53.393Z" }, + { url = "https://files.pythonhosted.org/packages/0d/01/add31fe76512642fd6e40e3a3bd21f4b47e242c8ba33efb6809e37076d9b/pyzmq-27.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:cedc4c68178e59a4046f97eca31b148ddcf51e88677de1ef4e78cf06c5376c9a", size = 1885316, upload-time = "2025-09-08T23:08:55.702Z" }, + { url = "https://files.pythonhosted.org/packages/c4/59/a5f38970f9bf07cee96128de79590bb354917914a9be11272cfc7ff26af0/pyzmq-27.1.0-cp314-cp314t-win32.whl", hash = "sha256:1f0b2a577fd770aa6f053211a55d1c47901f4d537389a034c690291485e5fe92", size = 587472, upload-time = "2025-09-08T23:08:58.18Z" }, + { url = "https://files.pythonhosted.org/packages/70/d8/78b1bad170f93fcf5e3536e70e8fadac55030002275c9a29e8f5719185de/pyzmq-27.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:19c9468ae0437f8074af379e986c5d3d7d7bfe033506af442e8c879732bedbe0", size = 661401, upload-time = "2025-09-08T23:08:59.802Z" }, + { url = "https://files.pythonhosted.org/packages/81/d6/4bfbb40c9a0b42fc53c7cf442f6385db70b40f74a783130c5d0a5aa62228/pyzmq-27.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:dc5dbf68a7857b59473f7df42650c621d7e8923fb03fa74a526890f4d33cc4d7", size = 575170, upload-time = "2025-09-08T23:09:01.418Z" }, +] + [[package]] name = "scikit-learn" version = "1.8.0" @@ -307,6 +676,20 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, ] +[[package]] +name = "stack-data" +version = "0.6.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "asttokens" }, + { name = "executing" }, + { name = "pure-eval" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/28/e3/55dcc2cfbc3ca9c29519eb6884dd1415ecb53b0e934862d3559ddcb7e20b/stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9", size = 44707, upload-time = "2023-09-30T13:58:05.479Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695", size = 24521, upload-time = "2023-09-30T13:58:03.53Z" }, +] + [[package]] name = "threadpoolctl" version = "3.6.0" @@ -316,6 +699,32 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/32/d5/f9a850d79b0851d1d4ef6456097579a9005b31fea68726a4ae5f2d82ddd9/threadpoolctl-3.6.0-py3-none-any.whl", hash = "sha256:43a0b8fd5a2928500110039e43a5eed8480b918967083ea48dc3ab9f13c4a7fb", size = 18638, upload-time = "2025-03-13T13:49:21.846Z" }, ] +[[package]] +name = "tornado" +version = "6.5.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/50/57/6d7303a77ae439d9189108f76c0c4fd89ee5e2cc8387bffb55232565c4ed/tornado-6.5.6.tar.gz", hash = "sha256:9a365179fe8ff6b8766f602c0f67c185d778193e9bdd828b19f0b6ed7764177d", size = 518139, upload-time = "2026-05-27T15:35:54.646Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1b/0d/b4f481e18c5a51864e6d12b9a05ecf72919696680b747c958c3fc1f4fbae/tornado-6.5.6-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:65fcfaafb079435c2c19dc9e07c0f1cf0fa9051759ed0a7d0a3ba7ea7f64919c", size = 447737, upload-time = "2026-05-27T15:35:38.122Z" }, + { url = "https://files.pythonhosted.org/packages/9e/9c/5430c39fcab1144d35860f457b15e9c08b4bc7ac86764354204e983d6183/tornado-6.5.6-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:38bc01b4acacded2de63ae78023548e41ebe6fbed3ec05a796d7ae3ad893887e", size = 445899, upload-time = "2026-05-27T15:35:40.519Z" }, + { url = "https://files.pythonhosted.org/packages/8b/79/fa7e14a2f939c807a8d30619b4eb604eab219601b78792516ebe22d40cf9/tornado-6.5.6-cp39-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b942e6a137fda31ff54bf8e6e2c8d1c37f1f50583f3ed53fb840b53b9601d104", size = 448964, upload-time = "2026-05-27T15:35:42.106Z" }, + { url = "https://files.pythonhosted.org/packages/a7/71/bd67d5f5199f937dafe03a49a37989f60f600ff6fef34c79412a829d97bd/tornado-6.5.6-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8666946e70171b8c3f1fc9b7876fac492e84822c4c7f3746f4e8f8bc9ac92a79", size = 449935, upload-time = "2026-05-27T15:35:43.906Z" }, + { url = "https://files.pythonhosted.org/packages/cc/a4/c24388c9cf5b3c3a513b56a158af9f23092c9a2810d789e294310797df21/tornado-6.5.6-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:1c34cfab7ad6d104f052f55de06d39bbafc5885cfeb4da688803308dbcfa90b7", size = 449767, upload-time = "2026-05-27T15:35:45.793Z" }, + { url = "https://files.pythonhosted.org/packages/a5/eb/6a07ad550c3f7b37244bd0becdf293ec3d3e961783d8b720a97df50de1b2/tornado-6.5.6-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:385f35e4e22fb52551dfcda4cdc8c30c61c2c001aef5ddad99cdfe116952efd3", size = 449174, upload-time = "2026-05-27T15:35:47.485Z" }, + { url = "https://files.pythonhosted.org/packages/bb/84/3469e098dccdb6763130e06aacd786bb4363fca7b590a55c101ddf34ed30/tornado-6.5.6-cp39-abi3-win32.whl", hash = "sha256:db475f1b67b2809b10bb16264829087724ca8d24fe4ed47f7b8675cae453ef86", size = 450230, upload-time = "2026-05-27T15:35:49.322Z" }, + { url = "https://files.pythonhosted.org/packages/d2/3c/273a04e0b9dd9016f1685cca0c1c8795a71ac88a34a8c889a0b443483226/tornado-6.5.6-cp39-abi3-win_amd64.whl", hash = "sha256:6739bf1e8eb09230f1280ddbd3236f0309db70f2c551a8dbc40f62babdf82f79", size = 450667, upload-time = "2026-05-27T15:35:51.194Z" }, + { url = "https://files.pythonhosted.org/packages/02/98/0cffe22a224f60c5fb1e3aa0b76f9da2e1ca78b0e9545e3d077c68ce60a7/tornado-6.5.6-cp39-abi3-win_arm64.whl", hash = "sha256:2543597b24a695d72338a9a77818362d72387c03ae173f1f169eadc5c91466ac", size = 449690, upload-time = "2026-05-27T15:35:52.902Z" }, +] + +[[package]] +name = "traitlets" +version = "5.15.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1b/22/40f55b26baeab80c2d7b3f1db0682f8954e4617fee7d90ce634022ef05c6/traitlets-5.15.0.tar.gz", hash = "sha256:4fead733f81cf1c4c938e06f8ca4633896833c9d89eff878159457f4d4392971", size = 163197, upload-time = "2026-05-06T08:05:58.016Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/da/98/a9937a969d018a23badfea0b381f66783649d48e0ea6c41923265c3cbeb3/traitlets-5.15.0-py3-none-any.whl", hash = "sha256:fb36a18867a6803deab09f3c5e0fa81bb7b26a5c9e82501c9933f759166eff40", size = 85877, upload-time = "2026-05-06T08:05:55.853Z" }, +] + [[package]] name = "tzdata" version = "2026.2" @@ -324,3 +733,12 @@ sdist = { url = "https://files.pythonhosted.org/packages/ba/19/1b9b0e29f30c6d35c wheels = [ { url = "https://files.pythonhosted.org/packages/ce/e4/dccd7f47c4b64213ac01ef921a1337ee6e30e8c6466046018326977efd95/tzdata-2026.2-py2.py3-none-any.whl", hash = "sha256:bbe9af844f658da81a5f95019480da3a89415801f6cc966806612cc7169bffe7", size = 349321, upload-time = "2026-04-24T15:22:05.876Z" }, ] + +[[package]] +name = "wcwidth" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2c/ee/afaf0f85a9a18fe47a67f1e4422ed6cf1fe642f0ae0a2f81166231303c52/wcwidth-0.7.0.tar.gz", hash = "sha256:90e3a7ea092341c44b99562e75d09e4d5160fe7a3974c6fb842a101a95e7eed0", size = 182132, upload-time = "2026-05-02T16:04:12.653Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/41/52/e465037f5375f43533d1a80b6923955201596a99142ed524d77b571a1418/wcwidth-0.7.0-py3-none-any.whl", hash = "sha256:5d69154c429a82910e241c738cd0e2976fac8a2dd47a1a805f4afed1c0f136f2", size = 110825, upload-time = "2026-05-02T16:04:11.033Z" }, +] From 4c1e72605f921c75e9de92fbc7e26246bf9f3682 Mon Sep 17 00:00:00 2001 From: brisson0916 Date: Fri, 12 Jun 2026 15:17:30 +0800 Subject: [PATCH 2/3] Submit encrypted cleaner --- .gitignore | 3 + main.ipynb | 1188 ++++++++++++++++++++------------------ submission/clean.py | 64 -- submission/clean.py.cms | Bin 0 -> 14954 bytes submission/manifest.json | 2 +- submission/manifest.sig | Bin 0 -> 512 bytes 6 files changed, 638 insertions(+), 619 deletions(-) delete mode 100644 submission/clean.py create mode 100644 submission/clean.py.cms create mode 100644 submission/manifest.sig diff --git a/.gitignore b/.gitignore index ed79207..4e75673 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,6 @@ admin/opentofu/terraform.tfstate* admin/opentofu/terraform.tfvars team_private_key.pem +clean_train.ipynb +weather_transformation.py +submission/clean.py \ No newline at end of file diff --git a/main.ipynb b/main.ipynb index 1d15775..64ab829 100644 --- a/main.ipynb +++ b/main.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 933, + "execution_count": 1194, "id": "76f1553e", "metadata": {}, "outputs": [], @@ -18,7 +18,7 @@ "import clean\n", "\n", "df = pd.read_csv(\"./data/test_features.csv\")\n", - "df = df[['origin_station',\n", + "df = df[['record_id','origin_station',\n", " 'destination_station',\n", " 'district',\n", " 'encoded_transport',\n", @@ -38,7 +38,7 @@ }, { "cell_type": "code", - "execution_count": 934, + "execution_count": 1195, "id": "63db2f09", "metadata": {}, "outputs": [], @@ -93,7 +93,7 @@ }, { "cell_type": "code", - "execution_count": 935, + "execution_count": 1196, "id": "f84f4f73", "metadata": {}, "outputs": [], @@ -128,7 +128,7 @@ }, { "cell_type": "code", - "execution_count": 936, + "execution_count": 1197, "id": "3be9e915", "metadata": {}, "outputs": [], @@ -159,7 +159,7 @@ }, { "cell_type": "code", - "execution_count": 937, + "execution_count": 1198, "id": "9a9bc0f9", "metadata": {}, "outputs": [ @@ -177,7 +177,7 @@ "Name: count, dtype: int64" ] }, - "execution_count": 937, + "execution_count": 1198, "metadata": {}, "output_type": "execute_result" } @@ -217,7 +217,7 @@ }, { "cell_type": "code", - "execution_count": 938, + "execution_count": 1199, "id": "8bc21583", "metadata": {}, "outputs": [ @@ -249,224 +249,224 @@ " \n", " \n", " \n", - " 1424\n", - " Causeway Bay\n", - " Central\n", - " Wan Chai\n", + " 516\n", + " NaN\n", + " NaN\n", + " NaN\n", + " \n", + " \n", + " 40\n", + " Kennedy Town\n", + " Mong Kok\n", + " Central and Western\n", " \n", " \n", - " 585\n", + " 1176\n", " Central\n", - " Tsuen Wan\n", + " Kennedy Town\n", " Central and Western\n", " \n", " \n", - " 1030\n", - " Causeway Bay\n", + " 429\n", " Mong Kok\n", - " Wan Chai\n", + " Central\n", + " Yau Tsim Mong\n", " \n", " \n", - " 1377\n", - " Kennedy Town\n", - " Central\n", - " Central and Western\n", + " 736\n", + " Tsim Sha Tsui\n", + " North Point\n", + " Yau Tsim Mong\n", " \n", " \n", - " 1723\n", + " 150\n", " Kennedy Town\n", " Mong Kok\n", " Central and Western\n", " \n", " \n", - " 1916\n", + " 368\n", + " Tsim Sha Tsui\n", + " Causeway Bay\n", + " Yau Tsim Mong\n", + " \n", + " \n", + " 1897\n", " NaN\n", " NaN\n", " NaN\n", " \n", " \n", - " 910\n", - " Causeway Bay\n", - " Central\n", - " Wan Chai\n", + " 674\n", + " North Point\n", + " Kennedy Town\n", + " Eastern\n", " \n", " \n", - " 527\n", + " 1322\n", " Kennedy Town\n", - " Tsim Sha Tsui\n", + " Admiralty\n", " Central and Western\n", " \n", " \n", - " 1020\n", - " Tsuen Wan\n", + " 1252\n", + " Causeway Bay\n", + " North Point\n", " Wan Chai\n", - " Tsuen Wan\n", " \n", " \n", - " 1888\n", - " North Point\n", + " 1801\n", + " NaN\n", + " NaN\n", + " NaN\n", + " \n", + " \n", + " 807\n", + " Causeway Bay\n", " Tsim Sha Tsui\n", - " Sha Tin\n", + " Wan Chai\n", " \n", " \n", - " 26\n", - " Mong Kok\n", + " 1534\n", " Central\n", - " Yau Tsim Mong\n", + " North Point\n", + " Central and Western\n", " \n", " \n", - " 1217\n", - " Wan Chai\n", - " North Point\n", - " Wan Chai\n", + " 896\n", + " NaN\n", + " NaN\n", + " NaN\n", " \n", " \n", - " 1197\n", - " Admiralty\n", - " Tsuen Wan\n", - " Central and Western\n", + " 842\n", + " Sha Tin\n", + " Tsim Sha Tsui\n", + " Sha Tin\n", " \n", " \n", - " 122\n", + " 1985\n", " Tsuen Wan\n", - " Mong Kok\n", + " Admiralty\n", " Tsuen Wan\n", " \n", " \n", - " 202\n", + " 1792\n", + " Central\n", " Mong Kok\n", - " North Point\n", - " Yau Tsim Mong\n", + " Central and Western\n", " \n", " \n", - " 154\n", + " 47\n", + " North Point\n", " Tsim Sha Tsui\n", - " Mong Kok\n", - " Yau Tsim Mong\n", - " \n", - " \n", - " 364\n", - " Kennedy Town\n", - " Sha Tin\n", - " Central and Western\n", + " Eastern\n", " \n", " \n", - " 450\n", + " 621\n", " Mong Kok\n", - " North Point\n", + " Causeway Bay\n", " Yau Tsim Mong\n", " \n", " \n", - " 298\n", + " 177\n", " Central\n", - " Causeway Bay\n", + " Mong Kok\n", " Central and Western\n", " \n", " \n", - " 1999\n", - " Sha Tin\n", - " Tsim Sha Tsui\n", - " Sha Tin\n", - " \n", - " \n", - " 959\n", + " 388\n", " North Point\n", " Tsuen Wan\n", " Eastern\n", " \n", " \n", - " 341\n", + " 1502\n", + " Causeway Bay\n", " North Point\n", " Wan Chai\n", - " Eastern\n", " \n", " \n", - " 790\n", + " 1958\n", + " Admiralty\n", + " Tsuen Wan\n", + " Central and Western\n", + " \n", + " \n", + " 1494\n", " Mong Kok\n", - " Causeway Bay\n", + " North Point\n", " Yau Tsim Mong\n", " \n", " \n", - " 1355\n", - " Wan Chai\n", + " 156\n", + " Central\n", " Tsuen Wan\n", - " Wan Chai\n", + " Central and Western\n", " \n", " \n", - " 294\n", + " 1704\n", " Central\n", - " Causeway Bay\n", + " Sha Tin\n", " Central and Western\n", " \n", " \n", - " 1463\n", - " North Point\n", - " Admiralty\n", - " Eastern\n", + " 1753\n", + " Causeway Bay\n", + " Kennedy Town\n", + " Wan Chai\n", " \n", " \n", - " 1026\n", + " 4\n", " North Point\n", " Central\n", - " Eastern\n", + " Sha Tin\n", " \n", " \n", - " 116\n", + " 2003\n", " Wan Chai\n", " Mong Kok\n", " Wan Chai\n", " \n", - " \n", - " 582\n", - " Causeway Bay\n", - " Wan Chai\n", - " Wan Chai\n", - " \n", - " \n", - " 83\n", - " Tsuen Wan\n", - " Wan Chai\n", - " Tsuen Wan\n", - " \n", " \n", "\n", "" ], "text/plain": [ " origin_station destination_station district\n", - "1424 Causeway Bay Central Wan Chai\n", - "585 Central Tsuen Wan Central and Western\n", - "1030 Causeway Bay Mong Kok Wan Chai\n", - "1377 Kennedy Town Central Central and Western\n", - "1723 Kennedy Town Mong Kok Central and Western\n", - "1916 NaN NaN NaN\n", - "910 Causeway Bay Central Wan Chai\n", - "527 Kennedy Town Tsim Sha Tsui Central and Western\n", - "1020 Tsuen Wan Wan Chai Tsuen Wan\n", - "1888 North Point Tsim Sha Tsui Sha Tin\n", - "26 Mong Kok Central Yau Tsim Mong\n", - "1217 Wan Chai North Point Wan Chai\n", - "1197 Admiralty Tsuen Wan Central and Western\n", - "122 Tsuen Wan Mong Kok Tsuen Wan\n", - "202 Mong Kok North Point Yau Tsim Mong\n", - "154 Tsim Sha Tsui Mong Kok Yau Tsim Mong\n", - "364 Kennedy Town Sha Tin Central and Western\n", - "450 Mong Kok North Point Yau Tsim Mong\n", - "298 Central Causeway Bay Central and Western\n", - "1999 Sha Tin Tsim Sha Tsui Sha Tin\n", - "959 North Point Tsuen Wan Eastern\n", - "341 North Point Wan Chai Eastern\n", - "790 Mong Kok Causeway Bay Yau Tsim Mong\n", - "1355 Wan Chai Tsuen Wan Wan Chai\n", - "294 Central Causeway Bay Central and Western\n", - "1463 North Point Admiralty Eastern\n", - "1026 North Point Central Eastern\n", - "116 Wan Chai Mong Kok Wan Chai\n", - "582 Causeway Bay Wan Chai Wan Chai\n", - "83 Tsuen Wan Wan Chai Tsuen Wan" + "516 NaN NaN NaN\n", + "40 Kennedy Town Mong Kok Central and Western\n", + "1176 Central Kennedy Town Central and Western\n", + "429 Mong Kok Central Yau Tsim Mong\n", + "736 Tsim Sha Tsui North Point Yau Tsim Mong\n", + "150 Kennedy Town Mong Kok Central and Western\n", + "368 Tsim Sha Tsui Causeway Bay Yau Tsim Mong\n", + "1897 NaN NaN NaN\n", + "674 North Point Kennedy Town Eastern\n", + "1322 Kennedy Town Admiralty Central and Western\n", + "1252 Causeway Bay North Point Wan Chai\n", + "1801 NaN NaN NaN\n", + "807 Causeway Bay Tsim Sha Tsui Wan Chai\n", + "1534 Central North Point Central and Western\n", + "896 NaN NaN NaN\n", + "842 Sha Tin Tsim Sha Tsui Sha Tin\n", + "1985 Tsuen Wan Admiralty Tsuen Wan\n", + "1792 Central Mong Kok Central and Western\n", + "47 North Point Tsim Sha Tsui Eastern\n", + "621 Mong Kok Causeway Bay Yau Tsim Mong\n", + "177 Central Mong Kok Central and Western\n", + "388 North Point Tsuen Wan Eastern\n", + "1502 Causeway Bay North Point Wan Chai\n", + "1958 Admiralty Tsuen Wan Central and Western\n", + "1494 Mong Kok North Point Yau Tsim Mong\n", + "156 Central Tsuen Wan Central and Western\n", + "1704 Central Sha Tin Central and Western\n", + "1753 Causeway Bay Kennedy Town Wan Chai\n", + "4 North Point Central Sha Tin\n", + "2003 Wan Chai Mong Kok Wan Chai" ] }, - "execution_count": 938, + "execution_count": 1199, "metadata": {}, "output_type": "execute_result" } @@ -485,7 +485,7 @@ }, { "cell_type": "code", - "execution_count": 939, + "execution_count": 1200, "id": "60b0a2db", "metadata": {}, "outputs": [ @@ -503,7 +503,7 @@ "Name: count, dtype: int64" ] }, - "execution_count": 939, + "execution_count": 1200, "metadata": {}, "output_type": "execute_result" } @@ -515,8 +515,48 @@ }, { "cell_type": "code", - "execution_count": 940, - "id": "534d4e8a", + "execution_count": 1201, + "id": "c69375a5", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['origin_station',\n", + " 'destination_station',\n", + " 'district',\n", + " 'transport_type',\n", + " 'transport_detail',\n", + " 'mode',\n", + " 'service_level',\n", + " 'operator',\n", + " 'day_of_week',\n", + " 'is_holiday',\n", + " 'weather_condition',\n", + " 'country_code']" + ] + }, + "execution_count": 1201, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "clean.SUBMISSION_FEATURES" + ] + }, + { + "cell_type": "markdown", + "id": "a02d34cf", + "metadata": {}, + "source": [ + "Cleaning encode_transport" + ] + }, + { + "cell_type": "code", + "execution_count": 1202, + "id": "30a35039", "metadata": {}, "outputs": [ { @@ -540,494 +580,246 @@ " \n", " \n", " \n", - " origin_station\n", - " destination_station\n", - " district\n", " encoded_transport\n", - " day_of_week\n", - " is_holiday\n", - " weather_condition\n", - " country_code\n", + " transport_type\n", + " transport_detail\n", + " mode\n", + " service_level\n", + " operator\n", " \n", " \n", " \n", " \n", - " 0\n", - " Sha Tin\n", - " Tsuen Wan\n", - " Sha Tin\n", - " tram_loc_std_citybus(src=endcap)(batch=L2)\n", - " Fri\n", - " 0\n", + " 229\n", + " UNK::bus::loc::kowloon\n", + " bus\n", + " general\n", + " local\n", " NaN\n", - " UNK\n", + " kowloon\n", " \n", " \n", - " 1\n", - " Tsuen Wan\n", - " Kennedy Town\n", - " Tsuen Wan\n", - " type=tram-xhbr;mode=loc;tier=missing;op=unknown\n", - " Thu\n", - " 0\n", + " 1861\n", + " kind,tram-apt,mode,loc,tier,std,op,citybus\n", " NaN\n", - " 852\n", + " general\n", + " NaN\n", + " NaN\n", + " citybus\n", " \n", " \n", - " 2\n", - " Causeway Bay\n", - " Wan Chai\n", - " Wan Chai\n", - " [tram][run=loc][tier=std][op=citybus][sys=L2]\n", - " Wed\n", - " 0\n", + " 1715\n", + " srcfeed::bus::loc::prem::citybus::delta\n", + " bus\n", + " general\n", + " local\n", + " premium\n", " NaN\n", - " territory-hk\n", " \n", " \n", - " 3\n", - " Admiralty\n", - " Causeway Bay\n", - " Central and Western\n", - " [bus-ngt][run=exp][tier=std][op=citybus][sys=L2]\n", - " Thu\n", - " 0\n", - " wx_unknown\n", - " legacy\n", + " 226\n", + " bus-apt__MISS__citybus\n", + " bus\n", + " airport\n", + " NaN\n", + " NaN\n", + " citybus\n", " \n", " \n", - " 4\n", - " North Point\n", - " Central\n", - " Sha Tin\n", - " L2::bus::exp::std::citybus::tail\n", - " Sat\n", - " 1\n", + " 1685\n", + " type=bus-xhbr;mode=exp;tier=missing;op=unknown\n", + " bus\n", + " crossharbour\n", + " express\n", + " NaN\n", " NaN\n", - " legacy\n", " \n", " \n", - " ...\n", - " ...\n", - " ...\n", - " ...\n", - " ...\n", - " ...\n", - " ...\n", - " ...\n", - " ...\n", + " 930\n", + " feed=OPS|kind=bus|run=loc|tier=prem|op=citybus\n", + " bus\n", + " general\n", + " local\n", + " premium\n", + " citybus\n", " \n", " \n", - " 2088\n", - " NaN\n", - " NaN\n", - " Sha Tin\n", - " maintenance_shift\n", - " Sun\n", - " 0\n", - " SUNNY\n", - " TST\n", + " 1397\n", + " bus-loc-std-citybus-c\n", + " bus\n", + " general\n", + " local\n", + " standard\n", + " citybus\n", " \n", " \n", - " 2089\n", - " Wan Chai\n", - " Central\n", - " Yau Tsim Mong\n", - " feed=OPS|kind=tram-ngt|run=exp|tier=std|op=cit...\n", - " Sat\n", - " 0\n", - " SUNNY\n", - " cc=852|OPS\n", - " \n", - " \n", - " 2090\n", - " Sha Tin\n", - " Tsuen Wan\n", - " Wan Chai\n", - " ferry__MISS__ferryhk\n", - " Tue\n", - " 0\n", - " heavy-rn\n", - " legacy-null\n", - " \n", - " \n", - " 2091\n", - " Mong Kok\n", - " Wan Chai\n", - " Yau Tsim Mong\n", - " L2::tram::exp::std::citybus::tail\n", - " Mon\n", - " 0\n", - " heavy-rn\n", - " territory-hk\n", - " \n", - " \n", - " 2092\n", - " Admiralty\n", - " Kennedy Town\n", - " Central and Western\n", - " vendor(kind=bus,mode=exp,tier=std,op=citybus)\n", - " Thu\n", - " 0\n", - " Unknown\n", - " N/A-HK\n", - " \n", - " \n", - "\n", - "

2093 rows × 8 columns

\n", - "" - ], - "text/plain": [ - " origin_station destination_station district \\\n", - "0 Sha Tin Tsuen Wan Sha Tin \n", - "1 Tsuen Wan Kennedy Town Tsuen Wan \n", - "2 Causeway Bay Wan Chai Wan Chai \n", - "3 Admiralty Causeway Bay Central and Western \n", - "4 North Point Central Sha Tin \n", - "... ... ... ... \n", - "2088 NaN NaN Sha Tin \n", - "2089 Wan Chai Central Yau Tsim Mong \n", - "2090 Sha Tin Tsuen Wan Wan Chai \n", - "2091 Mong Kok Wan Chai Yau Tsim Mong \n", - "2092 Admiralty Kennedy Town Central and Western \n", - "\n", - " encoded_transport day_of_week \\\n", - "0 tram_loc_std_citybus(src=endcap)(batch=L2) Fri \n", - "1 type=tram-xhbr;mode=loc;tier=missing;op=unknown Thu \n", - "2 [tram][run=loc][tier=std][op=citybus][sys=L2] Wed \n", - "3 [bus-ngt][run=exp][tier=std][op=citybus][sys=L2] Thu \n", - "4 L2::bus::exp::std::citybus::tail Sat \n", - "... ... ... \n", - "2088 maintenance_shift Sun \n", - "2089 feed=OPS|kind=tram-ngt|run=exp|tier=std|op=cit... Sat \n", - "2090 ferry__MISS__ferryhk Tue \n", - "2091 L2::tram::exp::std::citybus::tail Mon \n", - "2092 vendor(kind=bus,mode=exp,tier=std,op=citybus) Thu \n", - "\n", - " is_holiday weather_condition country_code \n", - "0 0 NaN UNK \n", - "1 0 NaN 852 \n", - "2 0 NaN territory-hk \n", - "3 0 wx_unknown legacy \n", - "4 1 NaN legacy \n", - "... ... ... ... \n", - "2088 0 SUNNY TST \n", - "2089 0 SUNNY cc=852|OPS \n", - "2090 0 heavy-rn legacy-null \n", - "2091 0 heavy-rn territory-hk \n", - "2092 0 Unknown N/A-HK \n", - "\n", - "[2093 rows x 8 columns]" - ] - }, - "execution_count": 940, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df" - ] - }, - { - "cell_type": "code", - "execution_count": 941, - "id": "c69375a5", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['origin_station',\n", - " 'destination_station',\n", - " 'district',\n", - " 'transport_type',\n", - " 'transport_detail',\n", - " 'mode',\n", - " 'service_level',\n", - " 'operator',\n", - " 'day_of_week',\n", - " 'is_holiday',\n", - " 'weather_condition',\n", - " 'country_code']" - ] - }, - "execution_count": 941, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "clean.SUBMISSION_FEATURES" - ] - }, - { - "cell_type": "code", - "execution_count": 942, - "id": "30a35039", - "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", - " \n", - " \n", + " \n", + " \n", " \n", " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", - " \n", - " \n", + " \n", " \n", " \n", + " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", " \n", " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", " \n", " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", " \n", "
encoded_transporttransport_typetransport_detailmodeservice_leveloperator
873type:tram|mode:loc|svc:std|owner:citybus|feed=OPStramgeneral1118ferry-apt.loc.std.ferryhkferryairportlocalstandardcitybusferryhk
1781maintenance_shiftNaNNaNNaN1592kind,tram,mode,loc,tier,std,op,citybusNaNNaN
856type=tram;mode=loc;tier=missing;op=unknowntramgenerallocalNaNNaNcitybus
474OPS::bus|loc|std|kowloon|v2709UNK::bus::loc::citybusbusgeneralNaNNaNkowloon
481UNK::tram::loc::citybustramgeneralNaNlocalNaNcitybus
1580srcfeed::tram::loc::std::citybus::deltatramgeneral1824kind,bus,mode,exp,tier,prem,op,citybusNaNgeneralNaNNaNcitybus
489amb::bus:loc:prem:citybus:??1979UNK::bus::loc::kowloonbusgenerallocalNaNcitybuskowloon
1850kind=bus-apt|kind=alt|run=?|tier=?|op=kowloon140L2::bus::loc::std::kowloon::tailbusairportNaNNaNgenerallocalstandardkowloon
178ferry__MISS__ferryhkNaNgeneralNaN2072[bus][run=loc][tier=std][op=citybus][sys=L2]NaNferryhk
926type=tram;mode=loc;tier=missing;op=unknowntramgenerallocalNaNNaNstandardcitybus
1792type=tram;mode=loc;tier=missing;op=unknowntram2084ferry-loc-std-ferryhk-cferrygenerallocalNaNNaN
44L2::bus::loc::std::kowloon::tailbusgeneralNaNNaNkowloonstandardferryhk
1891srcfeed::bus-apt::exp::std::kowloon::delta177kind=bus-night|kind=alt|run=?|tier=?|op=citybusbusairportNaNnightNaNNaNcitybus
245UNK::bus-apt::loc::kowloon1319bus-loc-std-kowloon-cbusairportNaNNaNgenerallocalstandardkowloon
1128bus-xhbrlocstdkowloon1132busexpstdkowloonbuscrossharbourNaNNaNkowloon
808UNK::tram::exp::citybustramgeneralNaNNaNcitybusexpressstandardkowloon
277UNK::tram::loc::citybustram941feed=OPS|kind=bus|run=loc|tier=std|op=citybusbusgeneralNaNNaNlocalstandardcitybus
1284buslocstdkowloon1852kind,bus,mode,loc,tier,std,op,kowloonNaNgeneralNaNNaNkowloon
1371tram.loc.prem.citybustramgeneralNaNNaNcitybus
584kind=bus-apt|kind=alt|run=?|tier=?|op=citybusbusairportNaNNaNcitybus
\n", "
" ], "text/plain": [ - " encoded_transport transport_type \\\n", - "873 type:tram|mode:loc|svc:std|owner:citybus|feed=OPS tram \n", - "1781 maintenance_shift NaN \n", - "856 type=tram;mode=loc;tier=missing;op=unknown tram \n", - "474 OPS::bus|loc|std|kowloon|v2 bus \n", - "481 UNK::tram::loc::citybus tram \n", - "1580 srcfeed::tram::loc::std::citybus::delta tram \n", - "489 amb::bus:loc:prem:citybus:?? bus \n", - "1850 kind=bus-apt|kind=alt|run=?|tier=?|op=kowloon bus \n", - "178 ferry__MISS__ferryhk NaN \n", - "926 type=tram;mode=loc;tier=missing;op=unknown tram \n", - "1792 type=tram;mode=loc;tier=missing;op=unknown tram \n", - "44 L2::bus::loc::std::kowloon::tail bus \n", - "1891 srcfeed::bus-apt::exp::std::kowloon::delta bus \n", - "245 UNK::bus-apt::loc::kowloon bus \n", - "1128 bus-xhbrlocstdkowloon bus \n", - "808 UNK::tram::exp::citybus tram \n", - "277 UNK::tram::loc::citybus tram \n", - "1284 buslocstdkowloon NaN \n", - "1371 tram.loc.prem.citybus tram \n", - "584 kind=bus-apt|kind=alt|run=?|tier=?|op=citybus bus \n", + " encoded_transport transport_type \\\n", + "229 UNK::bus::loc::kowloon bus \n", + "1861 kind,tram-apt,mode,loc,tier,std,op,citybus NaN \n", + "1715 srcfeed::bus::loc::prem::citybus::delta bus \n", + "226 bus-apt__MISS__citybus bus \n", + "1685 type=bus-xhbr;mode=exp;tier=missing;op=unknown bus \n", + "930 feed=OPS|kind=bus|run=loc|tier=prem|op=citybus bus \n", + "1397 bus-loc-std-citybus-c bus \n", + "1118 ferry-apt.loc.std.ferryhk ferry \n", + "1592 kind,tram,mode,loc,tier,std,op,citybus NaN \n", + "709 UNK::bus::loc::citybus bus \n", + "1824 kind,bus,mode,exp,tier,prem,op,citybus NaN \n", + "1979 UNK::bus::loc::kowloon bus \n", + "140 L2::bus::loc::std::kowloon::tail bus \n", + "2072 [bus][run=loc][tier=std][op=citybus][sys=L2] NaN \n", + "2084 ferry-loc-std-ferryhk-c ferry \n", + "177 kind=bus-night|kind=alt|run=?|tier=?|op=citybus bus \n", + "1319 bus-loc-std-kowloon-c bus \n", + "1132 busexpstdkowloon bus \n", + "941 feed=OPS|kind=bus|run=loc|tier=std|op=citybus bus \n", + "1852 kind,bus,mode,loc,tier,std,op,kowloon NaN \n", "\n", - " transport_detail mode service_level operator \n", - "873 general local standard citybus \n", - "1781 NaN NaN NaN NaN \n", - "856 general local NaN NaN \n", - "474 general NaN NaN kowloon \n", - "481 general NaN NaN citybus \n", - "1580 general NaN NaN NaN \n", - "489 general local NaN citybus \n", - "1850 airport NaN NaN kowloon \n", - "178 general NaN NaN ferryhk \n", - "926 general local NaN NaN \n", - "1792 general local NaN NaN \n", - "44 general NaN NaN kowloon \n", - "1891 airport NaN NaN NaN \n", - "245 airport NaN NaN kowloon \n", - "1128 crossharbour NaN NaN kowloon \n", - "808 general NaN NaN citybus \n", - "277 general NaN NaN citybus \n", - "1284 general NaN NaN kowloon \n", - "1371 general NaN NaN citybus \n", - "584 airport NaN NaN citybus " + " transport_detail mode service_level operator \n", + "229 general local NaN kowloon \n", + "1861 general NaN NaN citybus \n", + "1715 general local premium NaN \n", + "226 airport NaN NaN citybus \n", + "1685 crossharbour express NaN NaN \n", + "930 general local premium citybus \n", + "1397 general local standard citybus \n", + "1118 airport local standard ferryhk \n", + "1592 general NaN NaN citybus \n", + "709 general local NaN citybus \n", + "1824 general NaN NaN citybus \n", + "1979 general local NaN kowloon \n", + "140 general local standard kowloon \n", + "2072 general local standard citybus \n", + "2084 general local standard ferryhk \n", + "177 night NaN NaN citybus \n", + "1319 general local standard kowloon \n", + "1132 general express standard kowloon \n", + "941 general local standard citybus \n", + "1852 general NaN NaN kowloon " ] }, - "execution_count": 942, + "execution_count": 1202, "metadata": {}, "output_type": "execute_result" } @@ -1048,47 +840,59 @@ " return {'transport_type': pd.NA, 'transport_detail': pd.NA,\n", " 'mode': pd.NA, 'service_level': pd.NA, 'operator': pd.NA}\n", "\n", - " # transport_type\n", - " if re.search(r'\\btram\\b', v):\n", - " transport_type = 'tram'\n", - " elif re.search(r'\\bferry\\b', v):\n", - " transport_type = 'ferry'\n", - " elif re.search(r'\\bbus\\b', v):\n", - " transport_type = 'bus'\n", + " # transport_type - use flexible separators, handle word boundaries around them\n", + " m = re.search(r'(?:^|[_\\-|\\.::=])(tram|ferry|bus)(?:[_\\-|\\.::]|$)', v)\n", + " if not m:\n", + " # Try concatenated at start (e.g., buslocstdkowloon)\n", + " m = re.search(r'^(tram|ferry|bus)(loc|exp)(std|prem)', v)\n", + " if m:\n", + " transport_type = m.group(1)\n", " else:\n", " transport_type = pd.NA\n", "\n", " # transport_detail\n", - " m = re.search(r'(tram|ferry|bus)[-]?(apt|ngt|night|xhbr)', v)\n", + " m = re.search(r'(?:^|[_\\-|\\.::=])(tram|ferry|bus)[_\\-]?(apt|ngt|night|xhbr)', v)\n", " if m:\n", " detail_map = {'apt': 'airport', 'ngt': 'night', 'night': 'night', 'xhbr': 'crossharbour'}\n", " transport_detail = detail_map.get(m.group(2), 'general')\n", " else:\n", " transport_detail = 'general'\n", "\n", - " # mode\n", + " # mode - check multiple patterns\n", " m = re.search(r'\\b(?:run|mode)[=:](\\w+)', v)\n", " if m:\n", " mode_map = {'loc': 'local', 'exp': 'express'}\n", " mode = mode_map.get(m.group(1), pd.NA)\n", " else:\n", - " m = re.search(r'(tram|ferry|bus)[-]?\\w*[:_](\\w+)[:_]', v)\n", - " if m and m.group(2) in ('loc', 'exp'):\n", - " mode = 'local' if m.group(2) == 'loc' else 'express'\n", + " # Try standalone patterns with various separators: _loc_, .loc., |loc|, ::loc::\n", + " m = re.search(r'(?:^|[_\\-|\\.::])(loc|exp)(?:[_\\-|\\.::]|$)', v)\n", + " if m:\n", + " mode = 'local' if m.group(1) == 'loc' else 'express'\n", " else:\n", - " mode = pd.NA\n", + " # Concatenated: buslocstdkowloon, busexppremcitybus\n", + " m = re.search(r'(tram|ferry|bus)(loc|exp)(std|prem)', v)\n", + " if m:\n", + " mode = 'local' if m.group(2) == 'loc' else 'express'\n", + " else:\n", + " mode = pd.NA\n", "\n", - " # service_level\n", + " # service_level - check multiple patterns\n", " m = re.search(r'\\b(?:tier|svc)[=:](\\w+)', v)\n", " if m:\n", " sl_map = {'std': 'standard', 'prem': 'premium', 'missing': pd.NA}\n", " service_level = sl_map.get(m.group(1), pd.NA)\n", " else:\n", - " m = re.search(r'(tram|ferry|bus)[-]?\\w*[:_](\\w+)[:_]', v)\n", - " if m and m.group(2) in ('std', 'prem'):\n", - " service_level = 'standard' if m.group(2) == 'std' else 'premium'\n", + " # Try standalone patterns with various separators: _std_, .std., |std|, ::std::\n", + " m = re.search(r'(?:^|[_\\-|\\.::,])(std|prem)(?:[_\\-|\\.::]|$)', v)\n", + " if m:\n", + " service_level = 'standard' if m.group(1) == 'std' else 'premium'\n", " else:\n", - " service_level = pd.NA\n", + " # Concatenated: buslocstdkowloon, busexppremcitybus\n", + " m = re.search(r'(tram|ferry|bus)(loc|exp)(std|prem)', v)\n", + " if m:\n", + " service_level = 'standard' if m.group(3) == 'std' else 'premium'\n", + " else:\n", + " service_level = pd.NA\n", "\n", " # operator\n", " m = re.search(r'\\b(?:op|owner)[=:](\\w+)', v)\n", @@ -1138,28 +942,304 @@ }, { "cell_type": "code", - "execution_count": 943, + "execution_count": 1203, "id": "ea054597", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "operator\n", - "citybus 802\n", - "kowloon 599\n", - "NaN 438\n", - "ferryhk 254\n", + "mode\n", + "local 1097\n", + "NaN 651\n", + "express 345\n", "Name: count, dtype: int64" ] }, - "execution_count": 943, + "execution_count": 1203, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "df['operator'].value_counts(dropna=False).head(30)" + "df['mode'].value_counts(dropna=False).head(30)" + ] + }, + { + "cell_type": "code", + "execution_count": 1204, + "id": "3720f5af", + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
record_idorigin_stationdestination_stationdistrictday_of_weekis_holidayweather_conditioncountry_codetransport_typetransport_detailmodeservice_leveloperator
0R08001Sha TinTsuen WanSha TinFri0NaNUNKtramgenerallocalstandardNaN
1R08002Tsuen WanKennedy TownTsuen WanThu0NaN852tramcrossharbourlocalNaNNaN
2R08003Causeway BayWan ChaiWan ChaiWed0NaNterritory-hkNaNgenerallocalstandardcitybus
3R08004AdmiraltyCauseway BayCentral and WesternThu0wx_unknownlegacyNaNgeneralexpressstandardcitybus
4R08005North PointCentralSha TinSat1NaNlegacybusgeneralexpressstandardcitybus
..........................................
2088R09170NaNNaNSha TinSun0SUNNYTSTNaNNaNNaNNaNNaN
2089R08975Wan ChaiCentralYau Tsim MongSat0SUNNYcc=852|OPStramnightexpressstandardcitybus
2090R09878Sha TinTsuen WanWan ChaiTue0heavy-rnlegacy-nullferrygeneralNaNNaNferryhk
2091R08338Mong KokWan ChaiYau Tsim MongMon0heavy-rnterritory-hktramgeneralexpressstandardcitybus
2092R09934AdmiraltyKennedy TownCentral and WesternThu0UnknownN/A-HKNaNgeneralexpressstandardcitybus
\n", + "

2093 rows × 13 columns

\n", + "
" + ], + "text/plain": [ + " record_id origin_station destination_station district \\\n", + "0 R08001 Sha Tin Tsuen Wan Sha Tin \n", + "1 R08002 Tsuen Wan Kennedy Town Tsuen Wan \n", + "2 R08003 Causeway Bay Wan Chai Wan Chai \n", + "3 R08004 Admiralty Causeway Bay Central and Western \n", + "4 R08005 North Point Central Sha Tin \n", + "... ... ... ... ... \n", + "2088 R09170 NaN NaN Sha Tin \n", + "2089 R08975 Wan Chai Central Yau Tsim Mong \n", + "2090 R09878 Sha Tin Tsuen Wan Wan Chai \n", + "2091 R08338 Mong Kok Wan Chai Yau Tsim Mong \n", + "2092 R09934 Admiralty Kennedy Town Central and Western \n", + "\n", + " day_of_week is_holiday weather_condition country_code transport_type \\\n", + "0 Fri 0 NaN UNK tram \n", + "1 Thu 0 NaN 852 tram \n", + "2 Wed 0 NaN territory-hk NaN \n", + "3 Thu 0 wx_unknown legacy NaN \n", + "4 Sat 1 NaN legacy bus \n", + "... ... ... ... ... ... \n", + "2088 Sun 0 SUNNY TST NaN \n", + "2089 Sat 0 SUNNY cc=852|OPS tram \n", + "2090 Tue 0 heavy-rn legacy-null ferry \n", + "2091 Mon 0 heavy-rn territory-hk tram \n", + "2092 Thu 0 Unknown N/A-HK NaN \n", + "\n", + " transport_detail mode service_level operator \n", + "0 general local standard NaN \n", + "1 crossharbour local NaN NaN \n", + "2 general local standard citybus \n", + "3 general express standard citybus \n", + "4 general express standard citybus \n", + "... ... ... ... ... \n", + "2088 NaN NaN NaN NaN \n", + "2089 night express standard citybus \n", + "2090 general NaN NaN ferryhk \n", + "2091 general express standard citybus \n", + "2092 general express standard citybus \n", + "\n", + "[2093 rows x 13 columns]" + ] + }, + "execution_count": 1204, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.drop(columns='encoded_transport', inplace=True)\n", + "df" ] } ], diff --git a/submission/clean.py b/submission/clean.py deleted file mode 100644 index b1a07f9..0000000 --- a/submission/clean.py +++ /dev/null @@ -1,64 +0,0 @@ -from __future__ import annotations - -import argparse -import re -from pathlib import Path - -import pandas as pd - -SUBMISSION_FEATURES = [ - "origin_station", - "destination_station", - "district", - "transport_type", - "transport_detail", - "mode", - "service_level", - "operator", - "day_of_week", - "is_holiday", - "weather_condition", - "country_code", -] - -OUTPUT_COLUMNS = ["record_id", *SUBMISSION_FEATURES] - - -def parse_args() -> argparse.Namespace: - parser = argparse.ArgumentParser() - parser.add_argument("--train-input", required=True) - parser.add_argument("--train-output", required=True) - parser.add_argument("--test-input") - parser.add_argument("--test-output") - return parser.parse_args() - - -# Start input your code -# -# -# -# End of your code - - -def main() -> None: - args = parse_args() - train = pd.read_csv(args.train_input) - # Start input your code - # - # - # - # End of your code - Path(args.train_output).parent.mkdir(parents=True, exist_ok=True) - cleaned_train.to_csv(args.train_output, index=False) - - if args.test_input or args.test_output: - if not args.test_input or not args.test_output: - raise ValueError("--test-input and --test-output must be provided together") - test = pd.read_csv(args.test_input) - cleaned_test = _clean_frame(test) - Path(args.test_output).parent.mkdir(parents=True, exist_ok=True) - cleaned_test.to_csv(args.test_output, index=False) - - -if __name__ == "__main__": - main() diff --git a/submission/clean.py.cms b/submission/clean.py.cms new file mode 100644 index 0000000000000000000000000000000000000000..e843d3a4791035ce9c583f98bc6cbe4fe1f81dcf GIT binary patch literal 14954 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 Cy!spf literal 0 HcmV?d00001 From b3eed72d190eebafade9f074490c5889d8cb2f2d Mon Sep 17 00:00:00 2001 From: brisson0916 Date: Fri, 12 Jun 2026 15:27:21 +0800 Subject: [PATCH 3/3] Team 01: encrypted cleaner submission --- submission/clean.py.cms | Bin 14954 -> 14954 bytes submission/manifest.json | 2 +- submission/manifest.sig | Bin 512 -> 512 bytes 3 files changed, 1 insertion(+), 1 deletion(-) diff --git a/submission/clean.py.cms b/submission/clean.py.cms index e843d3a4791035ce9c583f98bc6cbe4fe1f81dcf..76665a05a97a801ff1c535d800f31eeda93553ed 100644 GIT binary patch delta 14884 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 Cy!spf