{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# default_exp datasets.retailrocket"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# RetailRocket Dataset\n",
    "> RetailRocket dataset."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#hide\n",
    "from nbdev.showdoc import *"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "from typing import List, Optional, Callable, Union, Any, Tuple\n",
    "\n",
    "import os\n",
    "import os.path as osp\n",
    "from collections.abc import Sequence\n",
    "import sys\n",
    "\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "from datetime import timezone, datetime, timedelta\n",
    "import time\n",
    "\n",
    "from recohut.utils.common_utils import download_url, extract_zip, makedirs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#exporti\n",
    "def to_list(value: Any) -> Sequence:\n",
    "    if isinstance(value, Sequence) and not isinstance(value, str):\n",
    "        return value\n",
    "    else:\n",
    "        return [value]\n",
    "\n",
    "def files_exist(files: List[str]) -> bool:\n",
    "    # NOTE: We return `False` in case `files` is empty, leading to a\n",
    "    # re-processing of files on every instantiation.\n",
    "    return len(files) != 0 and all([osp.exists(f) for f in files])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#exporti\n",
    "class Dataset:\n",
    "    \"\"\"Dataset base class\n",
    "    \"\"\"\n",
    "    @property\n",
    "    def raw_file_names(self) -> Union[str, List[str], Tuple]:\n",
    "        r\"\"\"The name of the files in the :obj:`self.raw_dir` folder that must\n",
    "        be present in order to skip downloading.\"\"\"\n",
    "        raise NotImplementedError\n",
    "\n",
    "    @property\n",
    "    def processed_file_names(self) -> Union[str, List[str], Tuple]:\n",
    "        r\"\"\"The name of the files in the :obj:`self.processed_dir` folder that\n",
    "        must be present in order to skip processing.\"\"\"\n",
    "        raise NotImplementedError\n",
    "\n",
    "    def download(self):\n",
    "        r\"\"\"Downloads the dataset to the :obj:`self.raw_dir` folder.\"\"\"\n",
    "        raise NotImplementedError\n",
    "\n",
    "    def process(self):\n",
    "        r\"\"\"Processes the dataset to the :obj:`self.processed_dir` folder.\"\"\"\n",
    "        raise NotImplementedError\n",
    "\n",
    "    def __init__(self, root=None):\n",
    "        self.root = root\n",
    "\n",
    "        if 'download' in self.__class__.__dict__:\n",
    "            self._download()\n",
    "\n",
    "        # if 'process' in self.__class__.__dict__:\n",
    "        #     self._process()\n",
    "\n",
    "    @property\n",
    "    def raw_dir(self) -> str:\n",
    "        return osp.join(self.root, 'raw')\n",
    "\n",
    "    @property\n",
    "    def processed_dir(self) -> str:\n",
    "        return osp.join(self.root, 'processed')\n",
    "\n",
    "    @property\n",
    "    def raw_paths(self) -> List[str]:\n",
    "        r\"\"\"The absolute filepaths that must be present in order to skip\n",
    "        downloading.\"\"\"\n",
    "        files = to_list(self.raw_file_names)\n",
    "        return [osp.join(self.raw_dir, f) for f in files]\n",
    "\n",
    "    @property\n",
    "    def processed_paths(self) -> List[str]:\n",
    "        r\"\"\"The absolute filepaths that must be present in order to skip\n",
    "        processing.\"\"\"\n",
    "        files = to_list(self.processed_file_names)\n",
    "        return [osp.join(self.processed_dir, f) for f in files]\n",
    "\n",
    "    def _download(self):\n",
    "        if files_exist(self.raw_paths):  # pragma: no cover\n",
    "            return\n",
    "\n",
    "        makedirs(self.raw_dir)\n",
    "        self.download()\n",
    "\n",
    "    def _process(self):\n",
    "        if files_exist(self.processed_paths):  # pragma: no cover\n",
    "            return\n",
    "\n",
    "        print('Processing...', file=sys.stderr)\n",
    "\n",
    "        makedirs(self.processed_dir)\n",
    "        self.process()\n",
    "\n",
    "        print('Done!', file=sys.stderr)\n",
    "\n",
    "    def __repr__(self) -> str:\n",
    "        arg_repr = str(len(self)) if len(self) > 1 else ''\n",
    "        return f'{self.__class__.__name__}({arg_repr})'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class RetailRocketDatasetv2(Dataset):\n",
    "    r\"\"\"Load and process RetailRocket dataset.\n",
    "\n",
    "    Args:\n",
    "        root (string): Root directory where the dataset should be saved.\n",
    "        process_method (string):\n",
    "            last: last day => test set\n",
    "            last_min_date: last day => test set, but from a minimal date onwards\n",
    "            days_test: last N days => test set\n",
    "            slice: create multiple train-test-combinations with a sliding window approach\n",
    "        min_date (string, optional): Minimum date\n",
    "        session_length (int, optional): Session time length :default = 30 * 60 #30 minutes\n",
    "        min_session_length (int, optional): Minimum number of items for a session to be valid\n",
    "        min_item_support (int, optional): Minimum number of interactions for an item to be valid\n",
    "        num_slices (int, optional): Offset in days from the first date in the data set\n",
    "        days_offset (int, optional): Number of days the training start date is shifted after creating one slice\n",
    "        days_shift (int, optional): Days shift\n",
    "        days_train (int, optional): Days in train set in each slice\n",
    "        days_test (int, optional): Days in test set in each slice\n",
    "    \"\"\"\n",
    "\n",
    "    url = 'https://github.com/RecoHut-Datasets/retail_rocket/raw/v2/retailrocket.zip'\n",
    "\n",
    "    def __init__(self, root, process_method, min_date='2015-09-02',\n",
    "                 session_length=30*60, min_session_length=2, min_item_support=5,\n",
    "                 num_slices=5, days_offset=0, days_shift=27, days_train=25, days_test=2):\n",
    "        super().__init__(root)\n",
    "        self.process_method = process_method\n",
    "        self.min_date = min_date\n",
    "        self.session_length = session_length\n",
    "        self.min_session_length = min_session_length\n",
    "        self.min_item_support = min_item_support\n",
    "        self.num_slices = num_slices\n",
    "        self.days_offset = days_offset\n",
    "        self.days_shift = days_shift\n",
    "        self.days_train = days_train\n",
    "        self.days_test = days_test\n",
    "        self.data = None\n",
    "        self.cart = None\n",
    "\n",
    "        self._process()\n",
    "\n",
    "    @property\n",
    "    def raw_file_names(self) -> str:\n",
    "        return 'events.csv'\n",
    "\n",
    "    @property\n",
    "    def processed_file_names(self) -> str:\n",
    "        return 'data.pkl'\n",
    "\n",
    "    def download(self):\n",
    "        path = download_url(self.url, self.raw_dir)\n",
    "        extract_zip(path, self.raw_dir)\n",
    "        from shutil import move, rmtree\n",
    "        move(osp.join(self.raw_dir, 'retailrocket', 'events.csv'),\n",
    "             osp.join(self.raw_dir, 'events.csv'))\n",
    "        rmtree(osp.join(self.raw_dir, 'retailrocket'))\n",
    "        os.unlink(path)\n",
    "\n",
    "    def load(self):\n",
    "        #load csv\n",
    "        data = pd.read_csv(osp.join(self.raw_dir,self.raw_file_names), sep=',',\n",
    "                           header=0, usecols=[0,1,2,3],\n",
    "                           dtype={0:np.int64, 1:np.int32, 2:str, 3:np.int32})\n",
    "        #specify header names\n",
    "        data.columns = ['Time','UserId','Type','ItemId']\n",
    "        data['Time'] = (data.Time / 1000).astype(int)\n",
    "        data.sort_values(['UserId','Time'], ascending=True, inplace=True)\n",
    "\n",
    "        #sessionize\n",
    "        data['TimeTmp'] = pd.to_datetime(data.Time, unit='s')\n",
    "        data.sort_values(['UserId','TimeTmp'], ascending=True, inplace=True)\n",
    "\n",
    "        data['TimeShift'] = data['TimeTmp'].shift(1)\n",
    "        data['TimeDiff'] = (data['TimeTmp'] - data['TimeShift']).dt.total_seconds().abs()\n",
    "        data['SessionIdTmp'] = (data['TimeDiff'] > self.session_length).astype(int)\n",
    "        data['SessionId'] = data['SessionIdTmp'].cumsum( skipna=False)\n",
    "        del data['SessionIdTmp'], data['TimeShift'], data['TimeDiff']\n",
    "\n",
    "        data.sort_values(['SessionId','Time'], ascending=True, inplace=True)\n",
    "\n",
    "        cart = data[data.Type == 'addtocart']\n",
    "        data = data[data.Type == 'view']\n",
    "        del data['Type']\n",
    "    \n",
    "        # output\n",
    "        print(data.Time.min())\n",
    "        print(data.Time.max())\n",
    "        data_start = datetime.fromtimestamp( data.Time.min(), timezone.utc)\n",
    "        data_end = datetime.fromtimestamp( data.Time.max(), timezone.utc)\n",
    "        del data['TimeTmp']\n",
    "    \n",
    "        print('Loaded data set\\n\\tEvents: {}\\n\\tSessions: {}\\n\\tItems: {}\\n\\tSpan: {} / {}\\n\\n'.\n",
    "              format(len(data), data.SessionId.nunique(), data.ItemId.nunique(), data_start.date().isoformat(), data_end.date().isoformat()))\n",
    "        \n",
    "        self.data = data\n",
    "        self.cart = cart\n",
    "\n",
    "    def filter_data(self): \n",
    "        data = self.data\n",
    "\n",
    "        #filter session length\n",
    "        session_lengths = data.groupby('SessionId').size()\n",
    "        data = data[np.in1d(data.SessionId, session_lengths[session_lengths>1].index)]\n",
    "        \n",
    "        #filter item support\n",
    "        item_supports = data.groupby('ItemId').size()\n",
    "        data = data[np.in1d(data.ItemId, item_supports[item_supports>= self.min_item_support].index)]\n",
    "        \n",
    "        #filter session length\n",
    "        session_lengths = data.groupby('SessionId').size()\n",
    "        data = data[np.in1d(data.SessionId, session_lengths[session_lengths>= self.min_session_length].index)]\n",
    "        \n",
    "        #output\n",
    "        data_start = datetime.fromtimestamp(data.Time.min(), timezone.utc)\n",
    "        data_end = datetime.fromtimestamp(data.Time.max(), timezone.utc)\n",
    "        \n",
    "        print('Filtered data set\\n\\tEvents: {}\\n\\tSessions: {}\\n\\tItems: {}\\n\\tSpan: {} / {}\\n\\n'.\n",
    "              format(len(data), data.SessionId.nunique(), data.ItemId.nunique(), data_start.date().isoformat(), data_end.date().isoformat()))\n",
    "    \n",
    "        self.data = data\n",
    "        \n",
    "    def filter_min_date(self):\n",
    "        data = self.data\n",
    "\n",
    "        min_datetime = datetime.strptime(self.min_date + ' 00:00:00', '%Y-%m-%d %H:%M:%S')\n",
    "        \n",
    "        #filter\n",
    "        session_max_times = data.groupby('SessionId').Time.max()\n",
    "        session_keep = session_max_times[session_max_times > min_datetime.timestamp()].index\n",
    "        \n",
    "        data = data[np.in1d(data.SessionId, session_keep)]\n",
    "        \n",
    "        #output\n",
    "        data_start = datetime.fromtimestamp(data.Time.min(), timezone.utc)\n",
    "        data_end = datetime.fromtimestamp(data.Time.max(), timezone.utc)\n",
    "        \n",
    "        print('Filtered data set\\n\\tEvents: {}\\n\\tSessions: {}\\n\\tItems: {}\\n\\tSpan: {} / {}\\n\\n'.\n",
    "              format(len(data), data.SessionId.nunique(), data.ItemId.nunique(), data_start.date().isoformat(), data_end.date().isoformat()))\n",
    "        \n",
    "        self.data = data\n",
    "\n",
    "    def split_data_org(self):\n",
    "        data = self.data\n",
    "        tmax = data.Time.max()\n",
    "        session_max_times = data.groupby('SessionId').Time.max()\n",
    "        session_train = session_max_times[session_max_times < tmax-86400].index\n",
    "        session_test = session_max_times[session_max_times >= tmax-86400].index\n",
    "        train = data[np.in1d(data.SessionId, session_train)]\n",
    "        test = data[np.in1d(data.SessionId, session_test)]\n",
    "        test = test[np.in1d(test.ItemId, train.ItemId)]\n",
    "        tslength = test.groupby('SessionId').size()\n",
    "        test = test[np.in1d(test.SessionId, tslength[tslength>=2].index)]\n",
    "        print('Full train set\\n\\tEvents: {}\\n\\tSessions: {}\\n\\tItems: {}'.format(len(train), train.SessionId.nunique(), train.ItemId.nunique()))\n",
    "        train.to_csv(osp.join(self.processed_dir,'events_train_full.txt'), sep='\\t', index=False)\n",
    "        print('Test set\\n\\tEvents: {}\\n\\tSessions: {}\\n\\tItems: {}'.format(len(test), test.SessionId.nunique(), test.ItemId.nunique()))\n",
    "        test.to_csv(osp.join(self.processed_dir,'events_test.txt'), sep='\\t', index=False)\n",
    "        \n",
    "        tmax = train.Time.max()\n",
    "        session_max_times = train.groupby('SessionId').Time.max()\n",
    "        session_train = session_max_times[session_max_times < tmax-86400].index\n",
    "        session_valid = session_max_times[session_max_times >= tmax-86400].index\n",
    "        train_tr = train[np.in1d(train.SessionId, session_train)]\n",
    "        valid = train[np.in1d(train.SessionId, session_valid)]\n",
    "        valid = valid[np.in1d(valid.ItemId, train_tr.ItemId)]\n",
    "        tslength = valid.groupby('SessionId').size()\n",
    "        valid = valid[np.in1d(valid.SessionId, tslength[tslength>=2].index)]\n",
    "        print('Train set\\n\\tEvents: {}\\n\\tSessions: {}\\n\\tItems: {}'.format(len(train_tr), train_tr.SessionId.nunique(), train_tr.ItemId.nunique()))\n",
    "        train_tr.to_csv(osp.join(self.processed_dir,'events_train_tr.txt'), sep='\\t', index=False)\n",
    "        print('Validation set\\n\\tEvents: {}\\n\\tSessions: {}\\n\\tItems: {}'.format(len(valid), valid.SessionId.nunique(), valid.ItemId.nunique()))\n",
    "        valid.to_csv(osp.join(self.processed_dir,'events_train_valid.txt'), sep='\\t', index=False)\n",
    "\n",
    "    def split_data(self):\n",
    "        data = self.data\n",
    "        data_end = datetime.fromtimestamp(data.Time.max(), timezone.utc)\n",
    "        test_from = data_end - timedelta(self.days_test)\n",
    "        \n",
    "        session_max_times = data.groupby('SessionId').Time.max()\n",
    "        session_train = session_max_times[session_max_times < test_from.timestamp()].index\n",
    "        session_test = session_max_times[session_max_times >= test_from.timestamp()].index\n",
    "        train = data[np.in1d(data.SessionId, session_train)]\n",
    "        test = data[np.in1d(data.SessionId, session_test)]\n",
    "        test = test[np.in1d(test.ItemId, train.ItemId)]\n",
    "        tslength = test.groupby('SessionId').size()\n",
    "        test = test[np.in1d(test.SessionId, tslength[tslength>=2].index)]\n",
    "        print('Full train set\\n\\tEvents: {}\\n\\tSessions: {}\\n\\tItems: {}'.format(len(train), train.SessionId.nunique(), train.ItemId.nunique()))\n",
    "        train.to_csv(osp.join(self.processed_dir,'events_train_full.txt'), sep='\\t', index=False)\n",
    "        print('Test set\\n\\tEvents: {}\\n\\tSessions: {}\\n\\tItems: {}'.format(len(test), test.SessionId.nunique(), test.ItemId.nunique()))\n",
    "        test.to_csv(osp.join(self.processed_dir,'events_test.txt'), sep='\\t', index=False)\n",
    "\n",
    "    def slice_data(self):\n",
    "        for slice_id in range(0, self.num_slices):\n",
    "            self.split_data_slice(slice_id, self.days_offset+(slice_id*self.days_shift))\n",
    "\n",
    "    def split_data_slice(self, slice_id, days_offset):\n",
    "        data = self.data\n",
    "        data_start = datetime.fromtimestamp(data.Time.min(), timezone.utc)\n",
    "        data_end = datetime.fromtimestamp(data.Time.max(), timezone.utc)\n",
    "        \n",
    "        print('Full data set {}\\n\\tEvents: {}\\n\\tSessions: {}\\n\\tItems: {}\\n\\tSpan: {} / {}'.\n",
    "            format(slice_id, len(data), data.SessionId.nunique(), data.ItemId.nunique(), data_start.isoformat(), data_end.isoformat()))    \n",
    "        \n",
    "        start = datetime.fromtimestamp(data.Time.min(), timezone.utc ) + timedelta(days_offset) \n",
    "        middle =  start + timedelta(self.days_train)\n",
    "        end =  middle + timedelta(self.days_test)\n",
    "        \n",
    "        #prefilter the timespan\n",
    "        session_max_times = data.groupby('SessionId').Time.max()\n",
    "        greater_start = session_max_times[session_max_times >= start.timestamp()].index\n",
    "        lower_end = session_max_times[session_max_times <= end.timestamp()].index\n",
    "        data_filtered = data[np.in1d(data.SessionId, greater_start.intersection(lower_end))]\n",
    "        \n",
    "        print('Slice data set {}\\n\\tEvents: {}\\n\\tSessions: {}\\n\\tItems: {}\\n\\tSpan: {} / {} / {}'.\n",
    "            format( slice_id, len(data_filtered), data_filtered.SessionId.nunique(), data_filtered.ItemId.nunique(), start.date().isoformat(), middle.date().isoformat(), end.date().isoformat() ) )\n",
    "        \n",
    "        #split to train and test\n",
    "        session_max_times = data_filtered.groupby('SessionId').Time.max()\n",
    "        sessions_train = session_max_times[session_max_times < middle.timestamp()].index\n",
    "        sessions_test = session_max_times[session_max_times >= middle.timestamp()].index\n",
    "        \n",
    "        train = data[np.in1d(data.SessionId, sessions_train)]\n",
    "        \n",
    "        print('Train set {}\\n\\tEvents: {}\\n\\tSessions: {}\\n\\tItems: {}\\n\\tSpan: {} / {}'.\n",
    "            format( slice_id, len(train), train.SessionId.nunique(), train.ItemId.nunique(), start.date().isoformat(), middle.date().isoformat() ) )\n",
    "        \n",
    "        train.to_csv(osp.join(self.processed_dir,'events_train_full.'+str(slice_id)+'.txt'), sep='\\t', index=False)\n",
    "        \n",
    "        test = data[np.in1d(data.SessionId, sessions_test)]\n",
    "        test = test[np.in1d(test.ItemId, train.ItemId)]\n",
    "        \n",
    "        tslength = test.groupby('SessionId').size()\n",
    "        test = test[np.in1d(test.SessionId, tslength[tslength>=2].index)]\n",
    "        \n",
    "        print('Test set {}\\n\\tEvents: {}\\n\\tSessions: {}\\n\\tItems: {}\\n\\tSpan: {} / {} \\n\\n'.\n",
    "            format( slice_id, len(test), test.SessionId.nunique(), test.ItemId.nunique(), middle.date().isoformat(), end.date().isoformat() ) )\n",
    "        \n",
    "        test.to_csv(osp.join(self.processed_dir,'events_test.'+str(slice_id)+'.txt'), sep='\\t', index=False)\n",
    "\n",
    "    def store_buys(self):\n",
    "        self.cart.to_csv(osp.join(self.processed_dir,'events_buys.txt'), sep='\\t', index=False)\n",
    "        \n",
    "    def process(self):\n",
    "        self.load()\n",
    "        self.filter_data()\n",
    "        if self.process_method == 'last':\n",
    "            self.split_data_org()\n",
    "        elif self.process_method == 'last_min_date':\n",
    "            self.filter_min_date()\n",
    "            self.split_data_org()\n",
    "        elif self.process_method == 'days_test':\n",
    "            self.split_data()\n",
    "        elif self.process_method == 'slice':\n",
    "            self.slice_data()\n",
    "        self.store_buys()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Processing...\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1430622011\n",
      "1442545187\n",
      "Loaded data set\n",
      "\tEvents: 2664312\n",
      "\tSessions: 1755206\n",
      "\tItems: 234838\n",
      "\tSpan: 2015-05-03 / 2015-09-18\n",
      "\n",
      "\n",
      "Filtered data set\n",
      "\tEvents: 1085763\n",
      "\tSessions: 306919\n",
      "\tItems: 49070\n",
      "\tSpan: 2015-05-03 / 2015-09-18\n",
      "\n",
      "\n",
      "Filtered data set\n",
      "\tEvents: 103032\n",
      "\tSessions: 30705\n",
      "\tItems: 23246\n",
      "\tSpan: 2015-09-01 / 2015-09-18\n",
      "\n",
      "\n",
      "Full train set\n",
      "\tEvents: 99363\n",
      "\tSessions: 29631\n",
      "\tItems: 22866\n",
      "Test set\n",
      "\tEvents: 2925\n",
      "\tSessions: 849\n",
      "\tItems: 1736\n",
      "Train set\n",
      "\tEvents: 95145\n",
      "\tSessions: 28467\n",
      "\tItems: 22325\n",
      "Validation set\n",
      "\tEvents: 3295\n",
      "\tSessions: 925\n",
      "\tItems: 1977\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Done!\n"
     ]
    }
   ],
   "source": [
    "rr = RetailRocketDatasetv2(root='/content/retailrocket', process_method='last_min_date')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Processing...\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1430622011\n",
      "1442545187\n",
      "Loaded data set\n",
      "\tEvents: 2664312\n",
      "\tSessions: 1755206\n",
      "\tItems: 234838\n",
      "\tSpan: 2015-05-03 / 2015-09-18\n",
      "\n",
      "\n",
      "Filtered data set\n",
      "\tEvents: 1085763\n",
      "\tSessions: 306919\n",
      "\tItems: 49070\n",
      "\tSpan: 2015-05-03 / 2015-09-18\n",
      "\n",
      "\n",
      "Full train set\n",
      "\tEvents: 1082094\n",
      "\tSessions: 305845\n",
      "\tItems: 49062\n",
      "Test set\n",
      "\tEvents: 3627\n",
      "\tSessions: 1065\n",
      "\tItems: 2190\n",
      "Train set\n",
      "\tEvents: 1077876\n",
      "\tSessions: 304681\n",
      "\tItems: 49058\n",
      "Validation set\n",
      "\tEvents: 4194\n",
      "\tSessions: 1162\n",
      "\tItems: 2606\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Done!\n"
     ]
    }
   ],
   "source": [
    "rr = RetailRocketDatasetv2(root='/content/retailrocket', process_method='last')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[01;34m/content/retailrocket\u001b[00m\n",
      "├── [104M]  \u001b[01;34mprocessed\u001b[00m\n",
      "│   ├── [4.1M]  events_buys.txt\n",
      "│   ├── [456K]  events_test.0.txt\n",
      "│   ├── [487K]  events_test.1.txt\n",
      "│   ├── [494K]  events_test.2.txt\n",
      "│   ├── [426K]  events_test.3.txt\n",
      "│   ├── [363K]  events_test.4.txt\n",
      "│   ├── [115K]  events_test.txt\n",
      "│   ├── [6.6M]  events_train_full.0.txt\n",
      "│   ├── [6.5M]  events_train_full.1.txt\n",
      "│   ├── [6.4M]  events_train_full.2.txt\n",
      "│   ├── [5.9M]  events_train_full.3.txt\n",
      "│   ├── [5.1M]  events_train_full.4.txt\n",
      "│   ├── [ 33M]  events_train_full.txt\n",
      "│   ├── [ 33M]  events_train_tr.txt\n",
      "│   └── [132K]  events_train_valid.txt\n",
      "└── [ 90M]  \u001b[01;34mraw\u001b[00m\n",
      "    └── [ 90M]  events.csv\n",
      "\n",
      " 194M used in 2 directories, 16 files\n"
     ]
    }
   ],
   "source": [
    "!tree --du -h -C /content/retailrocket"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Author: Sparsh A.\n",
      "\n",
      "Last updated: 2021-12-22 07:09:01\n",
      "\n",
      "recohut: 0.0.5\n",
      "\n",
      "Compiler    : GCC 7.5.0\n",
      "OS          : Linux\n",
      "Release     : 5.4.144+\n",
      "Machine     : x86_64\n",
      "Processor   : x86_64\n",
      "CPU cores   : 2\n",
      "Architecture: 64bit\n",
      "\n",
      "sys    : 3.7.12 (default, Sep 10 2021, 00:21:48) \n",
      "[GCC 7.5.0]\n",
      "pandas : 1.1.5\n",
      "numpy  : 1.19.5\n",
      "IPython: 5.5.0\n",
      "\n"
     ]
    }
   ],
   "source": [
    "#hide\n",
    "%reload_ext watermark\n",
    "%watermark -a \"Sparsh A.\" -m -iv -u -t -d -p recohut"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "name": "python3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
