{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#default_exp data.datasets.tourism"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Tourism dataset\n",
    "\n",
    "> Download the Tourism dataset.\n",
    "\n",
    "The tourism dataset corresponds to the 2010 Kaggle competition organized by  Athanasopoulos  et  al. The  dataset is comprised of [high frequency](https://www.kaggle.com/c/tourism2) data 366 monthly series, 427 quarterly series and 518 [lower frequency](https://www.kaggle.com/c/tourism1) annual series from the tourism economic sector. This dataset was built satisfying recommendations from the M3 competition to create time series datasets from homogeneous origins.\n",
    "\n",
    "[George Athanasopoulos, Rob J. Hyndman, Haiyan Song, and Doris C. Wu.  The tourism forecasting competition. International Journal of Forecasting,  27(3):822–844. Special Section 1: Forecasting with Artificial Neural Networks and Computational Intelligence. Special Section 2: Tourism Forecasting.](https://www.sciencedirect.com/science/article/abs/pii/S016920701000107X)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "import os\n",
    "from dataclasses import dataclass\n",
    "from typing import Dict, List, Optional, Tuple, Union\n",
    "\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "from pandas.tseries.frequencies import to_offset\n",
    "\n",
    "from nixtlats.data.datasets.utils import download_file, Info, TimeSeriesDataclass"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Tourism meta information"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@dataclass\n",
    "class Yearly:\n",
    "    seasonality: int = 1\n",
    "    horizon: int = 4\n",
    "    freq: str = 'Y'\n",
    "    rows: int = 2\n",
    "    name: str = 'Yearly'\n",
    "    n_ts: int = 518\n",
    "\n",
    "@dataclass\n",
    "class Quarterly:\n",
    "    seasonality: int = 4\n",
    "    horizon: int = 8\n",
    "    freq: str = 'Q'\n",
    "    rows: int = 3\n",
    "    name: str = 'Quarterly'\n",
    "    n_ts: int = 427\n",
    "\n",
    "@dataclass\n",
    "class Monthly:\n",
    "    seasonality: int = 12\n",
    "    horizon: int = 24\n",
    "    freq: str = 'M'\n",
    "    rows: int = 3\n",
    "    name: str = 'Monthly'\n",
    "    n_ts: int = 366"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "TourismInfo = Info(groups=('Yearly', 'Quarterly', 'Monthly'),\n",
    "                   class_groups=(Yearly, Quarterly, Monthly))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class Tourism(TimeSeriesDataclass):\n",
    "    \n",
    "    source_url = 'https://robjhyndman.com/data/27-3-Athanasopoulos1.zip'\n",
    "\n",
    "    @staticmethod\n",
    "    def load(directory: str,\n",
    "             group: str) -> Tuple[pd.DataFrame, \n",
    "                                  Optional[pd.DataFrame], \n",
    "                                  Optional[pd.DataFrame]]:\n",
    "        \"\"\"\n",
    "        Downloads and loads Tourism data.\n",
    "\n",
    "        Parameters\n",
    "        ----------\n",
    "        directory: str\n",
    "            Directory where data will be downloaded.\n",
    "        group: str\n",
    "            Group name.\n",
    "            Allowed groups: 'Yearly', 'Quarterly', 'Monthly'.\n",
    "    \n",
    "        Notes\n",
    "        -----\n",
    "        [1] Returns train+test sets.\n",
    "        \"\"\"\n",
    "        Tourism.download(directory)\n",
    "        \n",
    "        path = f'{directory}/tourism/datasets'\n",
    "        \n",
    "        class_group = TourismInfo.get_group(group)\n",
    "        train_file = f'{path}/{class_group.name.lower()}_in.csv'\n",
    "        test_file  = f'{path}/{class_group.name.lower()}_oos.csv'\n",
    "\n",
    "        train, test = pd.read_csv(train_file), pd.read_csv(test_file)\n",
    "\n",
    "        dfs = []\n",
    "        freq = to_offset(class_group.freq)\n",
    "        for col in train.columns:\n",
    "            df_appended = []\n",
    "            for df, training in zip([train, test], [True, False]):\n",
    "                df_col = df[col]\n",
    "                length, year = df_col[:2].astype(int)\n",
    "                skip_rows = class_group.rows\n",
    "                start_date = pd.to_datetime(f'{year}-01-01')\n",
    "                if group != 'Yearly':\n",
    "                    n_offsets = df_col[2].astype(int)\n",
    "                    start_date += n_offsets * freq\n",
    "                elif col == 'Y18' and not training: # viene mal en el archivo esta serie\n",
    "                    start_date += 2 * freq\n",
    "                df_col = df_col[skip_rows:length + skip_rows]\n",
    "                df_col = df_col.rename('y').to_frame()\n",
    "                df_col['unique_id'] = col\n",
    "                df_col['ds'] = pd.date_range(start_date, periods=length, freq=freq)\n",
    "                df_appended.append(df_col)\n",
    "            df_appended = pd.concat(df_appended)\n",
    "            dfs.append(df_appended)\n",
    "\n",
    "        df = pd.concat(dfs)\n",
    "\n",
    "        df = df.reset_index().filter(items=['unique_id', 'ds', 'y'])\n",
    "        df = df.sort_values(['unique_id', 'ds'])\n",
    "        \n",
    "        return df, None, None\n",
    "\n",
    "    @staticmethod\n",
    "    def download(directory: str) -> None:\n",
    "        \"\"\"Downloads Tourism Dataset.\"\"\"\n",
    "        path = f'{directory}/tourism/datasets'\n",
    "        \n",
    "        if not os.path.exists(path):\n",
    "            download_file(path, Tourism.source_url, decompress=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 356k/356k [00:00<00:00, 1.74MiB/s]\n",
      "INFO:nixtla.data.datasets.utils:Successfully downloaded 27-3-Athanasopoulos1.zip, 356334, bytes.\n",
      "INFO:nixtla.data.datasets.utils:Successfully decompressed data/tourism/datasets/27-3-Athanasopoulos1.zip\n"
     ]
    }
   ],
   "source": [
    "for group, meta in TourismInfo:\n",
    "    data, *_ = Tourism.load(directory='data', group=group)\n",
    "    unique_elements = data.groupby(['unique_id', 'ds']).size()\n",
    "    unique_ts = data.groupby('unique_id').size()\n",
    "\n",
    "    assert (unique_elements != 1).sum() == 0, f'Duplicated records found: {group}'\n",
    "    assert unique_ts.shape[0] == meta.n_ts, f'Number of time series not match: {group}'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
