{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":105399,"databundleVersionId":12733338,"sourceType":"competition"}],"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import polars as pl\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_train = pl.read_parquet('/kaggle/input/aeroclub-recsys-2025/train.parquet')\n# df_test = pl.read_parquet('/kaggle/input/aeroclub-recsys-2025/test.parquet')","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def _convert_datetime_columns(df, time_cols):\n    \"\"\"Конвертирует строковые колонки в datetime\"\"\"\n    return df.with_columns(\n        [pl.col(col).str.to_datetime() for col in time_cols]\n    )\n\ndef _create_time_features(df, datetime_col, prefix):\n    \"\"\"Создаёт фичи времени суток и сезона для указанной колонки\"\"\"\n    df = df.with_columns(\n        pl.when(pl.col(datetime_col).dt.hour().is_between(6, 11, closed='left'))\n        .then(pl.lit('morning'))\n        .when(pl.col(datetime_col).dt.hour().is_between(12, 17, closed='left'))\n        .then(pl.lit('afternoon'))\n        .when(pl.col(datetime_col).dt.hour().is_between(18, 23, closed='both'))\n        .then(pl.lit('night'))\n        .otherwise(pl.lit('early_morning'))\n        .alias(f'{prefix}_time_of_day')\n    )\n    \n    df = df.with_columns(\n        pl.when(pl.col(datetime_col).dt.month().is_in([12, 1, 2]))\n        .then(pl.lit('winter'))\n        .when(pl.col(datetime_col).dt.month().is_in([3, 4, 5]))\n        .then(pl.lit('spring'))\n        .when(pl.col(datetime_col).dt.month().is_in([6, 7, 8]))\n        .then(pl.lit('summer'))\n        .otherwise(pl.lit('autumn'))\n        .alias(f'{prefix}_season')\n    )\n    \n    return df\n\ndef _convert_duration_to_minutes(df, duration_cols):\n    \"\"\"Конвертирует duration колонки в минуты\"\"\"\n    return df.with_columns(\n        [\n            pl.col(col)\n            .str.strptime(pl.Duration, \"%H:%M:%S\")\n            .dt.total_minutes()\n            .alias(f\"{col}_minutes\")\n            for col in duration_cols\n        ]\n    )\n\ndef process_flight_data(df):\n    \"\"\"\n    Универсальная функция для обработки данных о полётах.\n    Применяется одинаково к train и test данным.\n    \"\"\"\n    \n    # Колонки для удаления\n    cols_to_drop =  ['corporateTariffCode',\n     'frequentFlyer',\n     'legs0_segments1_aircraft_code',\n     'legs0_segments1_arrivalTo_airport_city_iata',\n     'legs0_segments1_arrivalTo_airport_iata',\n     'legs0_segments1_baggageAllowance_quantity',\n     'legs0_segments1_baggageAllowance_weightMeasurementType',\n     'legs0_segments1_cabinClass',\n     'legs0_segments1_departureFrom_airport_iata',\n     'legs0_segments1_duration',\n     'legs0_segments1_flightNumber',\n     'legs0_segments1_marketingCarrier_code',\n     'legs0_segments1_operatingCarrier_code',\n     'legs0_segments1_seatsAvailable',\n     'legs0_segments2_aircraft_code',\n     'legs0_segments2_arrivalTo_airport_city_iata',\n     'legs0_segments2_arrivalTo_airport_iata',\n     'legs0_segments2_baggageAllowance_quantity',\n     'legs0_segments2_baggageAllowance_weightMeasurementType',\n     'legs0_segments2_cabinClass',\n     'legs0_segments2_departureFrom_airport_iata',\n     'legs0_segments2_duration',\n     'legs0_segments2_flightNumber',\n     'legs0_segments2_marketingCarrier_code',\n     'legs0_segments2_operatingCarrier_code',\n     'legs0_segments2_seatsAvailable',\n     'legs0_segments3_aircraft_code',\n     'legs0_segments3_arrivalTo_airport_city_iata',\n     'legs0_segments3_arrivalTo_airport_iata',\n     'legs0_segments3_baggageAllowance_quantity',\n     'legs0_segments3_baggageAllowance_weightMeasurementType',\n     'legs0_segments3_cabinClass',\n     'legs0_segments3_departureFrom_airport_iata',\n     'legs0_segments3_duration',\n     'legs0_segments3_flightNumber',\n     'legs0_segments3_marketingCarrier_code',\n     'legs0_segments3_operatingCarrier_code',\n     'legs0_segments3_seatsAvailable',\n     'legs1_segments1_aircraft_code',\n     'legs1_segments1_arrivalTo_airport_city_iata',\n     'legs1_segments1_arrivalTo_airport_iata',\n     'legs1_segments1_baggageAllowance_quantity',\n     'legs1_segments1_baggageAllowance_weightMeasurementType',\n     'legs1_segments1_cabinClass',\n     'legs1_segments1_departureFrom_airport_iata',\n     'legs1_segments1_duration',\n     'legs1_segments1_flightNumber',\n     'legs1_segments1_marketingCarrier_code',\n     'legs1_segments1_operatingCarrier_code',\n     'legs1_segments1_seatsAvailable',\n     'legs1_segments2_aircraft_code',\n     'legs1_segments2_arrivalTo_airport_city_iata',\n     'legs1_segments2_arrivalTo_airport_iata',\n     'legs1_segments2_baggageAllowance_quantity',\n     'legs1_segments2_baggageAllowance_weightMeasurementType',\n     'legs1_segments2_cabinClass',\n     'legs1_segments2_departureFrom_airport_iata',\n     'legs1_segments2_duration',\n     'legs1_segments2_flightNumber',\n     'legs1_segments2_marketingCarrier_code',\n     'legs1_segments2_operatingCarrier_code',\n     'legs1_segments2_seatsAvailable',\n     'legs1_segments3_aircraft_code',\n     'legs1_segments3_arrivalTo_airport_city_iata',\n     'legs1_segments3_arrivalTo_airport_iata',\n     'legs1_segments3_baggageAllowance_quantity',\n     'legs1_segments3_baggageAllowance_weightMeasurementType',\n     'legs1_segments3_cabinClass',\n     'legs1_segments3_departureFrom_airport_iata',\n     'legs1_segments3_duration',\n     'legs1_segments3_flightNumber',\n     'legs1_segments3_marketingCarrier_code',\n     'legs1_segments3_operatingCarrier_code',\n     'legs1_segments3_seatsAvailable',\n     'miniRules0_percentage',\n     'miniRules1_percentage',\n     '__index_level_0__'\n    ]\n    \n    # Удаляем только существующие колонки\n    cols_to_drop_existing = [col for col in cols_to_drop if col in df.columns]\n    df = df.drop(cols_to_drop_existing)\n    \n    # Конвертируем datetime колонки\n    time_cols = ['legs0_arrivalAt', 'legs0_departureAt', 'legs1_arrivalAt', \n                 'legs1_departureAt', 'requestDate']\n    df = _convert_datetime_columns(df, time_cols)\n    \n    # Создаём временные фичи\n    df = _create_time_features(df, 'legs0_departureAt', 'departure')\n    df = _create_time_features(df, 'legs1_departureAt', 'return_departure')\n    df = _create_time_features(df, 'requestDate', 'request')\n    \n    # Удаляем исходные datetime колонки\n    df = df.drop(time_cols)\n    \n    # Конвертируем duration в минуты\n    duration_cols = ['legs0_duration', 'legs1_duration', 'legs1_segments0_duration']\n    df = _convert_duration_to_minutes(df, duration_cols)\n    df = df.drop(duration_cols)\n    \n    return df\n\n# Использование:\ndf_train = process_flight_data(df_train)\n# df_test = process_flight_data(df_test)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_train","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}