{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport os, sys\nfrom pathlib import Path\nimport pickle\nimport tensorflow as tf\nfrom tensorflow.keras.layers import Normalization, Discretization\nfrom tensorflow.keras.layers import CategoryEncoding, Hashing, StringLookup, IntegerLookup","metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","papermill":{"duration":0.095722,"end_time":"2022-03-07T19:12:26.109785","exception":false,"start_time":"2022-03-07T19:12:26.014063","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-04-17T18:51:16.786657Z","iopub.execute_input":"2022-04-17T18:51:16.787554Z","iopub.status.idle":"2022-04-17T18:51:23.843932Z","shell.execute_reply.started":"2022-04-17T18:51:16.787427Z","shell.execute_reply":"2022-04-17T18:51:23.843035Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pd.options.display.max_columns = 500","metadata":{"execution":{"iopub.status.busy":"2022-04-17T18:51:23.845446Z","iopub.execute_input":"2022-04-17T18:51:23.845694Z","iopub.status.idle":"2022-04-17T18:51:23.849931Z","shell.execute_reply.started":"2022-04-17T18:51:23.84566Z","shell.execute_reply":"2022-04-17T18:51:23.849084Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"DATA_DIR = '../input/h-and-m-personalized-fashion-recommendations/'\nIMAGE_DIR = '../input/hm-image-features-w-resnet50/'\nTEXT_DIR = '../input/hm-text-features-w-roberta/'","metadata":{"papermill":{"duration":0.069767,"end_time":"2022-03-07T19:12:26.241221","exception":false,"start_time":"2022-03-07T19:12:26.171454","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-04-17T18:51:23.851088Z","iopub.execute_input":"2022-04-17T18:51:23.851885Z","iopub.status.idle":"2022-04-17T18:51:23.876131Z","shell.execute_reply.started":"2022-04-17T18:51:23.851841Z","shell.execute_reply":"2022-04-17T18:51:23.875393Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"csv_list = [os.path.join(DATA_DIR, p) for p in os.listdir(DATA_DIR) if p.endswith('.csv') if p != 'sample_submission.csv']","metadata":{"papermill":{"duration":0.045132,"end_time":"2022-03-07T19:12:26.324662","exception":false,"start_time":"2022-03-07T19:12:26.27953","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-04-17T18:51:23.878Z","iopub.execute_input":"2022-04-17T18:51:23.878349Z","iopub.status.idle":"2022-04-17T18:51:23.889083Z","shell.execute_reply.started":"2022-04-17T18:51:23.878316Z","shell.execute_reply":"2022-04-17T18:51:23.888455Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def reduce_mem_usage(df, verbose=True):\n    numerics = ['int16', 'int32', 'int64', 'float16', 'float32', 'float64']\n    start_mem = df.memory_usage().sum() / 1024**2\n    for col in df.columns:\n        col_type = df[col].dtypes\n        if col_type in numerics:\n            c_min = df[col].min()\n            c_max = df[col].max()\n            if str(col_type)[:3] == 'int':\n                if c_min > np.iinfo(np.int8).min and c_max < np.iinfo(np.int8).max:\n                    df[col] = df[col].astype(np.int8)\n                elif c_min > np.iinfo(np.int16).min and c_max < np.iinfo(np.int16).max:\n                    df[col] = df[col].astype(np.int16)\n                elif c_min > np.iinfo(np.int32).min and c_max < np.iinfo(np.int32).max:\n                    df[col] = df[col].astype(np.int32)\n                elif c_min > np.iinfo(np.int64).min and c_max < np.iinfo(np.int64).max:\n                    df[col] = df[col].astype(np.int64)  \n            else:\n                if c_min > np.finfo(np.float16).min and c_max < np.finfo(np.float16).max:\n                    df[col] = df[col].astype(np.float16)\n                elif c_min > np.finfo(np.float32).min and c_max < np.finfo(np.float32).max:\n                    df[col] = df[col].astype(np.float32)\n                else:\n                    df[col] = df[col].astype(np.float64)    \n    end_mem = df.memory_usage().sum() / 1024**2\n    if verbose: print('Mem. usage decreased to {:5.2f} Mb ({:.1f}% reduction)'.format(end_mem, 100 * (start_mem - end_mem) / start_mem))\n    return df","metadata":{"papermill":{"duration":0.053007,"end_time":"2022-03-07T19:12:26.41648","exception":false,"start_time":"2022-03-07T19:12:26.363473","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-04-17T18:51:23.890196Z","iopub.execute_input":"2022-04-17T18:51:23.890737Z","iopub.status.idle":"2022-04-17T18:51:23.906931Z","shell.execute_reply.started":"2022-04-17T18:51:23.890672Z","shell.execute_reply":"2022-04-17T18:51:23.905688Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# reading all csv\ndata = {}\nfor file_path in csv_list:\n    file_name = file_path.split('.')[-2].split(\"/\")[-1].strip(\" \")\n    print(f\"Reading {file_name}.csv\")\n    data[file_name] = reduce_mem_usage(pd.read_csv(file_path))","metadata":{"papermill":{"duration":73.108789,"end_time":"2022-03-07T19:13:39.562716","exception":false,"start_time":"2022-03-07T19:12:26.453927","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-04-17T18:51:23.90818Z","iopub.execute_input":"2022-04-17T18:51:23.908459Z","iopub.status.idle":"2022-04-17T18:52:47.442485Z","shell.execute_reply.started":"2022-04-17T18:51:23.908428Z","shell.execute_reply":"2022-04-17T18:52:47.441569Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for k, v in data.items():\n    print(f\"******** {k} ********\")\n    print(v.head(2))","metadata":{"papermill":{"duration":0.065172,"end_time":"2022-03-07T19:13:39.667872","exception":false,"start_time":"2022-03-07T19:13:39.6027","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-04-17T18:52:47.443687Z","iopub.execute_input":"2022-04-17T18:52:47.443946Z","iopub.status.idle":"2022-04-17T18:52:47.4675Z","shell.execute_reply.started":"2022-04-17T18:52:47.443916Z","shell.execute_reply":"2022-04-17T18:52:47.466435Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for k, v in data.items():\n    print(f\"******** {k} ********\")\n    print(v.shape, v.columns.tolist())","metadata":{"papermill":{"duration":0.048829,"end_time":"2022-03-07T19:13:39.75592","exception":false,"start_time":"2022-03-07T19:13:39.707091","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-04-17T18:52:47.469269Z","iopub.execute_input":"2022-04-17T18:52:47.469834Z","iopub.status.idle":"2022-04-17T18:52:47.476311Z","shell.execute_reply.started":"2022-04-17T18:52:47.469788Z","shell.execute_reply":"2022-04-17T18:52:47.475345Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Image features","metadata":{}},{"cell_type":"code","source":"# with open(os.path.join(IMAGE_DIR, 'image_df.pkl'), 'rb') as f:\n#     image_df = pickle.load(f)\n#     image_df['image_features'] = image_df['image_features'].apply(lambda x: x.tolist())\n#     image_df.sample(4)","metadata":{"execution":{"iopub.status.busy":"2022-04-17T18:52:47.477671Z","iopub.execute_input":"2022-04-17T18:52:47.477903Z","iopub.status.idle":"2022-04-17T18:52:47.491913Z","shell.execute_reply.started":"2022-04-17T18:52:47.477876Z","shell.execute_reply":"2022-04-17T18:52:47.49116Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Text features","metadata":{}},{"cell_type":"code","source":"# with open(os.path.join(TEXT_DIR, 'text_df.pkl'), 'rb') as f:\n#     text_df = pickle.load(f)\n#     text_df['detail_desc_features'] = text_df['detail_desc_features'].apply(lambda x: x.tolist())\n#     text_df.head(4)","metadata":{"execution":{"iopub.status.busy":"2022-04-17T18:52:47.494993Z","iopub.execute_input":"2022-04-17T18:52:47.49568Z","iopub.status.idle":"2022-04-17T18:52:47.509795Z","shell.execute_reply.started":"2022-04-17T18:52:47.495639Z","shell.execute_reply":"2022-04-17T18:52:47.508706Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Customer Feature Extraction Pipeline\n\nFN is if a customer get Fashion News newsletter, Active is if the customer is active for communication, sales channel id, 2 is online and 1 store.\n\nGrouping postal codes based on sales and number of customers","metadata":{"papermill":{"duration":0.0396,"end_time":"2022-03-07T19:13:39.837227","exception":false,"start_time":"2022-03-07T19:13:39.797627","status":"completed"},"tags":[]}},{"cell_type":"code","source":"data['customers'].head()","metadata":{"papermill":{"duration":0.05945,"end_time":"2022-03-07T19:13:39.936316","exception":false,"start_time":"2022-03-07T19:13:39.876866","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-04-17T18:52:47.512262Z","iopub.execute_input":"2022-04-17T18:52:47.512634Z","iopub.status.idle":"2022-04-17T18:52:47.539432Z","shell.execute_reply.started":"2022-04-17T18:52:47.51259Z","shell.execute_reply":"2022-04-17T18:52:47.538488Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data['customers'].isna().sum()","metadata":{"papermill":{"duration":0.582895,"end_time":"2022-03-07T19:13:40.559202","exception":false,"start_time":"2022-03-07T19:13:39.976307","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-04-17T18:52:47.541019Z","iopub.execute_input":"2022-04-17T18:52:47.541376Z","iopub.status.idle":"2022-04-17T18:52:48.207423Z","shell.execute_reply.started":"2022-04-17T18:52:47.541331Z","shell.execute_reply":"2022-04-17T18:52:48.206539Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data['customers'].info()","metadata":{"papermill":{"duration":0.595031,"end_time":"2022-03-07T19:13:41.195164","exception":false,"start_time":"2022-03-07T19:13:40.600133","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-04-17T18:52:48.208513Z","iopub.execute_input":"2022-04-17T18:52:48.20872Z","iopub.status.idle":"2022-04-17T18:52:48.887335Z","shell.execute_reply.started":"2022-04-17T18:52:48.208695Z","shell.execute_reply":"2022-04-17T18:52:48.8863Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data['customers'].nunique()","metadata":{"papermill":{"duration":1.414338,"end_time":"2022-03-07T19:13:42.650221","exception":false,"start_time":"2022-03-07T19:13:41.235883","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-04-17T18:52:48.888576Z","iopub.execute_input":"2022-04-17T18:52:48.888847Z","iopub.status.idle":"2022-04-17T18:52:50.753036Z","shell.execute_reply.started":"2022-04-17T18:52:48.888786Z","shell.execute_reply":"2022-04-17T18:52:50.752156Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data['customers'].describe()","metadata":{"papermill":{"duration":0.873977,"end_time":"2022-03-07T19:13:43.565413","exception":false,"start_time":"2022-03-07T19:13:42.691436","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-04-17T18:52:50.754163Z","iopub.execute_input":"2022-04-17T18:52:50.754416Z","iopub.status.idle":"2022-04-17T18:52:51.760296Z","shell.execute_reply.started":"2022-04-17T18:52:50.754389Z","shell.execute_reply":"2022-04-17T18:52:51.759363Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data['customers']['age'] = data['customers']['age'].astype('float32')\ndata['customers']['club_member_status'] = data['customers']['club_member_status'].str.lower()\ndata['customers']['fashion_news_frequency'] = data['customers']['fashion_news_frequency'].str.lower()\n\nmissing_value_impute_dict = {\n    'FN': 0.0,\n    'Active': 0.0,\n    'club_member_status': 'Not Applicable',\n    'fashion_news_frequency': 'NONE',\n    'age': np.round(data['customers']['age'].mean())\n}\n\nfor col, impute_value in missing_value_impute_dict.items():\n    data['customers'][col].loc[data['customers'][col].isna()] = impute_value","metadata":{"execution":{"iopub.status.busy":"2022-04-17T18:52:51.761449Z","iopub.execute_input":"2022-04-17T18:52:51.761663Z","iopub.status.idle":"2022-04-17T18:52:53.567784Z","shell.execute_reply.started":"2022-04-17T18:52:51.76163Z","shell.execute_reply":"2022-04-17T18:52:53.566831Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"{col:data['customers'][col].unique() for col in data['customers'] if col not in ['customer_id', 'postal_code']}","metadata":{"execution":{"iopub.status.busy":"2022-04-17T18:52:53.568892Z","iopub.execute_input":"2022-04-17T18:52:53.569843Z","iopub.status.idle":"2022-04-17T18:52:53.877722Z","shell.execute_reply.started":"2022-04-17T18:52:53.569806Z","shell.execute_reply":"2022-04-17T18:52:53.876795Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Key observations\n1. The transaction data is not at the correct level and hence will need to be aggregated to `t_dat`, `article_id`, `customer_id`, `sales_channel_id` , `price` level  and `qty` column to be created to adjust for the missing information (28805603 rows vs 31788324 rows)\n2. `article_id` and `product_code` seem to map n-to-1\n3. Submission dataset has some customers which are not present in transaction file or customer file\n`data['sample_submission']['customer_id'].nunique(), data['customers']['customer_id'].nunique(), data['transactions_train']['customer_id'].nunique()` --> 1371980, 1371980, 1362281\n4. Breaking the data into 7 day rolling periods can be a good way generate data (a lot of it)","metadata":{}},{"cell_type":"markdown","source":"## Transactions Feature Extraction Pipeline","metadata":{"papermill":{"duration":0.041526,"end_time":"2022-03-07T19:13:43.651864","exception":false,"start_time":"2022-03-07T19:13:43.610338","status":"completed"},"tags":[]}},{"cell_type":"code","source":"seeded_value = 8888\npd.set_option('display.max_colwidth', 50)\nnp.random.seed(seeded_value)\n\n# suppress scientific notation\npd.options.display.precision = 2\nnp.set_printoptions(suppress=True)\npd.set_option('display.float_format', lambda x: '%.2f' % x)","metadata":{"papermill":{"duration":0.049418,"end_time":"2022-03-07T19:13:43.742627","exception":false,"start_time":"2022-03-07T19:13:43.693209","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-04-17T18:52:53.879188Z","iopub.execute_input":"2022-04-17T18:52:53.880098Z","iopub.status.idle":"2022-04-17T18:52:53.886797Z","shell.execute_reply.started":"2022-04-17T18:52:53.880043Z","shell.execute_reply":"2022-04-17T18:52:53.885932Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data['transactions_train'].shape","metadata":{"papermill":{"duration":0.050202,"end_time":"2022-03-07T19:13:43.83537","exception":false,"start_time":"2022-03-07T19:13:43.785168","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-04-17T18:52:53.888089Z","iopub.execute_input":"2022-04-17T18:52:53.888357Z","iopub.status.idle":"2022-04-17T18:52:53.905018Z","shell.execute_reply.started":"2022-04-17T18:52:53.888324Z","shell.execute_reply":"2022-04-17T18:52:53.903969Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data['transactions_train'].nunique()","metadata":{"papermill":{"duration":9.930892,"end_time":"2022-03-07T19:13:53.808483","exception":false,"start_time":"2022-03-07T19:13:43.877591","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-04-17T18:52:53.906689Z","iopub.execute_input":"2022-04-17T18:52:53.906946Z","iopub.status.idle":"2022-04-17T18:53:08.605258Z","shell.execute_reply.started":"2022-04-17T18:52:53.906916Z","shell.execute_reply":"2022-04-17T18:53:08.604249Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data['transactions_train'].info()","metadata":{"papermill":{"duration":0.054354,"end_time":"2022-03-07T19:13:53.908633","exception":false,"start_time":"2022-03-07T19:13:53.854279","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-04-17T18:53:08.607146Z","iopub.execute_input":"2022-04-17T18:53:08.607462Z","iopub.status.idle":"2022-04-17T18:53:08.623036Z","shell.execute_reply.started":"2022-04-17T18:53:08.607422Z","shell.execute_reply":"2022-04-17T18:53:08.622053Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data['transactions_train']['t_dat'].describe()","metadata":{"papermill":{"duration":0.054354,"end_time":"2022-03-07T19:13:53.908633","exception":false,"start_time":"2022-03-07T19:13:53.854279","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-04-17T18:53:08.624651Z","iopub.execute_input":"2022-04-17T18:53:08.62494Z","iopub.status.idle":"2022-04-17T18:53:15.867996Z","shell.execute_reply.started":"2022-04-17T18:53:08.624898Z","shell.execute_reply":"2022-04-17T18:53:15.86703Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data['transactions_train']['t_dat'].min(), data['transactions_train']['t_dat'].max()","metadata":{"execution":{"iopub.status.busy":"2022-04-17T18:53:15.8697Z","iopub.execute_input":"2022-04-17T18:53:15.870011Z","iopub.status.idle":"2022-04-17T18:53:25.360189Z","shell.execute_reply.started":"2022-04-17T18:53:15.869969Z","shell.execute_reply":"2022-04-17T18:53:25.359135Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dates_set = data['transactions_train']['t_dat'].sort_values().unique().tolist()","metadata":{"execution":{"iopub.status.busy":"2022-04-17T18:53:25.361383Z","iopub.execute_input":"2022-04-17T18:53:25.361598Z","iopub.status.idle":"2022-04-17T18:54:16.346061Z","shell.execute_reply.started":"2022-04-17T18:53:25.361573Z","shell.execute_reply":"2022-04-17T18:54:16.345215Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"NUM_DATES = len(dates_set)\nprint(NUM_DATES)","metadata":{"execution":{"iopub.status.busy":"2022-04-17T18:54:16.347394Z","iopub.execute_input":"2022-04-17T18:54:16.347621Z","iopub.status.idle":"2022-04-17T18:54:16.352771Z","shell.execute_reply.started":"2022-04-17T18:54:16.347593Z","shell.execute_reply":"2022-04-17T18:54:16.35172Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data['transactions_train']['t_dat'] = pd.to_datetime(data['transactions_train']['t_dat'], format = (\"%Y-%m-%d\"))","metadata":{"execution":{"iopub.status.busy":"2022-04-17T18:54:16.353977Z","iopub.execute_input":"2022-04-17T18:54:16.354362Z","iopub.status.idle":"2022-04-17T18:54:22.72946Z","shell.execute_reply.started":"2022-04-17T18:54:16.35433Z","shell.execute_reply":"2022-04-17T18:54:22.728713Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"m = data['transactions_train'].groupby(['article_id'], as_index=False)[['t_dat']].agg({'t_dat':min})\nm2 = m.groupby('t_dat', as_index=False)['article_id'].count().sort_values('t_dat', ascending=True)\nm2['cmltve'] = 100 * m2['article_id'].cumsum() / m2['article_id'].sum()","metadata":{"execution":{"iopub.status.busy":"2022-04-17T18:54:22.730766Z","iopub.execute_input":"2022-04-17T18:54:22.731161Z","iopub.status.idle":"2022-04-17T18:54:24.089312Z","shell.execute_reply.started":"2022-04-17T18:54:22.731116Z","shell.execute_reply":"2022-04-17T18:54:24.088662Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"m2[['t_dat', 'cmltve']].plot(x='t_dat', y='cmltve', figsize=(10,6))","metadata":{"execution":{"iopub.status.busy":"2022-04-17T18:54:24.093643Z","iopub.execute_input":"2022-04-17T18:54:24.094015Z","iopub.status.idle":"2022-04-17T18:54:24.511275Z","shell.execute_reply.started":"2022-04-17T18:54:24.093972Z","shell.execute_reply":"2022-04-17T18:54:24.51057Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"PERCENTILE_CUTOFF = 80 # percent 0 -- 100\nPERCENTILE_PRODUCT_COVERED_DATE = str(m2['t_dat'].loc[m2['cmltve'] > 80].min())[:10]\nprint(PERCENTILE_PRODUCT_COVERED_DATE, np.round(100 * dates_set.index(PERCENTILE_PRODUCT_COVERED_DATE) / len(dates_set)))","metadata":{"execution":{"iopub.status.busy":"2022-04-17T18:54:24.512574Z","iopub.execute_input":"2022-04-17T18:54:24.513377Z","iopub.status.idle":"2022-04-17T18:54:24.521046Z","shell.execute_reply.started":"2022-04-17T18:54:24.513342Z","shell.execute_reply":"2022-04-17T18:54:24.520302Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def preprocess_dates(data, datecolname):\n    data['date_time'] = pd.to_datetime(data[datecolname], format = (\"%Y-%m-%d\"))\n#     print({\n#         \"min_\": data[\"date_time\"].min(),\n#         \"max_\": data[\"date_time\"].max(),\n#         \"nunique_\": data[\"date_time\"].nunique()\n#     })\n    data['year_dt'] = data['date_time'].dt.year.astype('int16')\n    data['month_dt'] = data['date_time'].dt.month.astype('int16')\n    data['day_dt'] = data['date_time'].dt.day.astype('int16')\n    data['weekofyear_dt'] = data['date_time'].dt.isocalendar().week.astype('int16')\n    data['dayofweek_dt'] = data['date_time'].dt.dayofweek.astype('int16') + 1 \n    data['dayofyear_dt'] = data['date_time'].dt.dayofyear.astype('int16')\n    data['quarter_dt'] = data['date_time'].dt.quarter.astype('int16')\n    data['is_month_start_dt'] = data['date_time'].dt.is_month_start.astype('int16')\n    data['is_month_end_dt'] = data['date_time'].dt.is_month_end.astype('int16')\n    data['is_quarter_start_dt'] = data['date_time'].dt.is_quarter_start.astype('int16')\n    data['is_quarter_end_dt'] = data['date_time'].dt.is_quarter_end.astype('int16')\n    data['is_year_start_dt'] = data['date_time'].dt.is_year_start.astype('int16')\n    data['is_year_end_dt'] = data['date_time'].dt.is_year_end.astype('int16')\n    data['is_leap_year_dt'] = data['date_time'].dt.is_leap_year.astype('int16')\n    data['daysinmonth_dt'] = data['date_time'].dt.daysinmonth.astype('int16')\n    return data","metadata":{"execution":{"iopub.status.busy":"2022-04-17T19:47:04.150943Z","iopub.execute_input":"2022-04-17T19:47:04.15152Z","iopub.status.idle":"2022-04-17T19:47:04.163088Z","shell.execute_reply.started":"2022-04-17T19:47:04.15148Z","shell.execute_reply":"2022-04-17T19:47:04.162322Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"date_columns = [\n    'year_dt', 'month_dt', 'day_dt', 'week_dt', \n    'dayofweek_dt', 'weekday_dt', 'dayofyear_dt', 'quarter_dt',\n    'is_month_start_dt', 'is_month_end_dt', 'is_quarter_start_dt',\n    'is_quarter_end_dt', 'is_year_start_dt', 'is_year_end_dt',\n    'is_leap_year_dt', 'daysinmonth_dt'\n]","metadata":{"execution":{"iopub.status.busy":"2022-04-17T19:42:33.700634Z","iopub.execute_input":"2022-04-17T19:42:33.701418Z","iopub.status.idle":"2022-04-17T19:42:33.706823Z","shell.execute_reply.started":"2022-04-17T19:42:33.701374Z","shell.execute_reply":"2022-04-17T19:42:33.705816Z"}},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def merge_additional_info(dataset):\n    results = dataset.merge(data['customers'], on='customer_id', how='left')\n    results = results.merge(image_df[['article_id', 'image_features']], on='article_id', how='left')\n    KEEP_COLS = [col for col in text_df.columns if col not in ['prod_name', 'detail_desc']]\n    results = results.merge(text_df[KEEP_COLS], on='article_id', how='left')\n    return results","metadata":{"execution":{"iopub.status.busy":"2022-04-17T19:42:35.159012Z","iopub.execute_input":"2022-04-17T19:42:35.159296Z","iopub.status.idle":"2022-04-17T19:42:35.166153Z","shell.execute_reply.started":"2022-04-17T19:42:35.159268Z","shell.execute_reply":"2022-04-17T19:42:35.165105Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Strategy:\n1. Most popular baseline (in the training data)\n2. Repeat last ordered item baseline (in the training data)\n3. Experiments\n    1. Users & Products only\n    2. Order features\n    3. Customer features\n    4. Add date parts\n    5. Product features\n        1. Product metadata\n        2. Product Image\n        3. Product Description\n","metadata":{}},{"cell_type":"code","source":"def slice_and_agg(dates_subset, dates_subset_y):\n    data_slice_y = data['transactions_train'].loc[(data['transactions_train']['t_dat'].isin(dates_subset_y))].copy()\n    data_slice_y = data_slice_y.groupby('customer_id', as_index=False).agg({\n        'article_id': lambda x: x.tolist()\n    }).rename(columns={'article_id':'y'})[['customer_id', 'y']]\n    \n    print(data_slice_y['customer_id'].nunique(), \"customers found in validation period..\")\n    \n    data_slice = data['transactions_train'].loc[(data['transactions_train']['t_dat'].isin(dates_subset))].copy()\n    data_slice = data_slice.loc[(data['transactions_train']['customer_id'].isin(data_slice_y['customer_id'].unique()))].copy()\n    data_slice['qty'] = 1\n    \n    print(data_slice['customer_id'].nunique(), \"customers found in training period..\")\n    \n    TXN_GROUP_COLS = ['t_dat', 'customer_id', 'sales_channel_id', 'article_id', 'price']\n\n    data_slice = data_slice.groupby(TXN_GROUP_COLS, as_index=False).agg({'qty': 'sum'}).sort_values([\n        't_dat', 'customer_id', 'sales_channel_id', 'article_id', 'price'\n    ],ascending=[\n        True, True, True, True , True\n    ])\n\n#     data_slice = merge_additional_info(data_slice)\n    data_slice = preprocess_dates(data_slice, 't_dat')\n    data_slice = data_slice.groupby('customer_id', as_index=False).agg({\n        col: lambda x: x.tolist()\n        for col in data_slice.columns # TXN_GROUP_COLS + ['qty'] + date_columns\n        if col not in ['customer_id', 't_dat', 'date_time']\n    }).reset_index(drop=True)\n    \n    results = data_slice.merge(data_slice_y, how='inner', on='customer_id')\n    print(results['customer_id'].nunique(), \"customers found in the final dataset..\")\n    return results","metadata":{"execution":{"iopub.status.busy":"2022-04-17T19:42:37.481561Z","iopub.execute_input":"2022-04-17T19:42:37.481876Z","iopub.status.idle":"2022-04-17T19:42:37.493872Z","shell.execute_reply.started":"2022-04-17T19:42:37.481841Z","shell.execute_reply":"2022-04-17T19:42:37.493198Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Preprocessing module","metadata":{}},{"cell_type":"code","source":"CAT_FEATURES = [\n    'product_code', 'product_type_no', 'product_type_name', 'product_group_name', 'graphical_appearance_no', 'graphical_appearance_name',\n    'colour_group_code', 'colour_group_name', 'perceived_colour_value_id', 'perceived_colour_value_name', 'perceived_colour_master_id',\n    'perceived_colour_master_name', 'department_no', 'department_name', 'index_code', 'index_name', 'index_group_no', 'index_group_name',\n    'section_no', 'section_name', 'garment_group_no', 'garment_group_name'\n]\n\nCAT_FEATURES = CAT_FEATURES + [\n    'customer_id', 'FN', 'Active', 'club_member_status', 'fashion_news_frequency', 'postal_code'\n] + [\n    'sales_channel_id', 'article_id', \n    'month_dt', 'day_dt', 'week_dt', 'weekofyear_dt', 'dayofweek_dt', 'dayofyear_dt', 'quarter_dt', \n]\n\nCONT_FEATURES = [\n    'age', 'price', 'year_dt', 'qty',\n    'is_month_start_dt', 'is_month_end_dt', 'is_quarter_start_dt', 'is_quarter_end_dt', \n    'is_year_start_dt', 'is_year_end_dt', 'is_leap_year_dt', 'daysinmonth_dt',\n]\n\nTEXT_FEATURES = ['detail_desc_features']\n\nIMAGE_FEATURES = ['image_features']\n\nDEP_FEATURES = ['y']","metadata":{"execution":{"iopub.status.busy":"2022-04-17T19:42:39.675147Z","iopub.execute_input":"2022-04-17T19:42:39.675983Z","iopub.status.idle":"2022-04-17T19:42:39.684142Z","shell.execute_reply.started":"2022-04-17T19:42:39.675947Z","shell.execute_reply":"2022-04-17T19:42:39.683159Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Setting up the train validation and CV","metadata":{}},{"cell_type":"code","source":"dates_set_array = np.array(dates_set)","metadata":{"execution":{"iopub.status.busy":"2022-04-17T19:42:42.01203Z","iopub.execute_input":"2022-04-17T19:42:42.012633Z","iopub.status.idle":"2022-04-17T19:42:42.016551Z","shell.execute_reply.started":"2022-04-17T19:42:42.012577Z","shell.execute_reply":"2022-04-17T19:42:42.015694Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_validation_indices = [\n    (\n        list(range(0, i * 7)), \n        list(range(i * 7, (i + 1) * 7)),\n        list(range((i + 1) * 7, (i + 2) * 7))\n    )\n    for i in range((len(dates_set) // 7) + 1)\n    if i != 0\n]","metadata":{"execution":{"iopub.status.busy":"2022-04-17T19:42:43.17219Z","iopub.execute_input":"2022-04-17T19:42:43.172517Z","iopub.status.idle":"2022-04-17T19:42:43.179138Z","shell.execute_reply.started":"2022-04-17T19:42:43.172481Z","shell.execute_reply":"2022-04-17T19:42:43.178563Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# for train_i, valid_i, test_i in train_validation_indices:\ntrain_i, valid_i, test_i = train_validation_indices[0]\ntrain_df = slice_and_agg(dates_set_array[train_i], dates_set_array[valid_i])\nvalid_df = slice_and_agg(dates_set_array[train_i + valid_i], dates_set_array[test_i])","metadata":{"execution":{"iopub.status.busy":"2022-04-17T19:42:44.699119Z","iopub.execute_input":"2022-04-17T19:42:44.699414Z","iopub.status.idle":"2022-04-17T19:43:02.403402Z","shell.execute_reply.started":"2022-04-17T19:42:44.699386Z","shell.execute_reply":"2022-04-17T19:43:02.402293Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Preprocessing","metadata":{}},{"cell_type":"markdown","source":"1. Date columns will not have a missing value hence no need for a mask_value","metadata":{}},{"cell_type":"markdown","source":"#### Padding and Truncation","metadata":{}},{"cell_type":"code","source":"MAX_SEQ_LEN = 10","metadata":{"execution":{"iopub.status.busy":"2022-04-17T19:58:59.579482Z","iopub.execute_input":"2022-04-17T19:58:59.579776Z","iopub.status.idle":"2022-04-17T19:58:59.584071Z","shell.execute_reply.started":"2022-04-17T19:58:59.579741Z","shell.execute_reply":"2022-04-17T19:58:59.583246Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# P = ['1.1', '2.0']\n# # P = ['1', '2']\n# # P = [1.2,2.2]\n# # P = [1,2]\n\n# print(type(P[0]))\n\n# np.array([0]*5 + P, dtype=type(P[0])).tolist()","metadata":{"execution":{"iopub.status.busy":"2022-04-17T20:06:42.835997Z","iopub.execute_input":"2022-04-17T20:06:42.836307Z","iopub.status.idle":"2022-04-17T20:06:42.845149Z","shell.execute_reply.started":"2022-04-17T20:06:42.83627Z","shell.execute_reply":"2022-04-17T20:06:42.844312Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def truncate_and_add_padding(x: list, max_seq_len: int, padding_value: int=0):\n    dtype_ = type(x[0])\n    x = x[-max_seq_len:]\n    len_ = len(x)\n    return np.array([padding_value] * (max_seq_len - len_) + x, dtype=dtype_).tolist()","metadata":{"execution":{"iopub.status.busy":"2022-04-17T20:13:30.480126Z","iopub.execute_input":"2022-04-17T20:13:30.480461Z","iopub.status.idle":"2022-04-17T20:13:30.486678Z","shell.execute_reply.started":"2022-04-17T20:13:30.480426Z","shell.execute_reply":"2022-04-17T20:13:30.485719Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_data = {\n    col: train_df[col].apply(lambda x: truncate_and_add_padding(x, MAX_SEQ_LEN)).tolist()\n    if col not in ['customer_id', 'y']\n    else train_df[col].tolist()\n    for col in train_df.columns\n}","metadata":{"execution":{"iopub.status.busy":"2022-04-17T20:13:31.705284Z","iopub.execute_input":"2022-04-17T20:13:31.705858Z","iopub.status.idle":"2022-04-17T20:13:34.263571Z","shell.execute_reply.started":"2022-04-17T20:13:31.705811Z","shell.execute_reply":"2022-04-17T20:13:34.262675Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### https://www.tensorflow.org/guide/keras/preprocessing_layers#preprocessing_data_before_the_model_or_inside_the_model","metadata":{}},{"cell_type":"code","source":"train_df.columns","metadata":{"execution":{"iopub.status.busy":"2022-04-17T20:13:36.373211Z","iopub.execute_input":"2022-04-17T20:13:36.373522Z","iopub.status.idle":"2022-04-17T20:13:36.380482Z","shell.execute_reply.started":"2022-04-17T20:13:36.37349Z","shell.execute_reply":"2022-04-17T20:13:36.379567Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_data['customer_id'][:5]","metadata":{"execution":{"iopub.status.busy":"2022-04-17T20:13:36.766211Z","iopub.execute_input":"2022-04-17T20:13:36.766534Z","iopub.status.idle":"2022-04-17T20:13:36.773416Z","shell.execute_reply.started":"2022-04-17T20:13:36.766504Z","shell.execute_reply":"2022-04-17T20:13:36.772566Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Hashing processing -- flat dimensions\ninput_layer = tf.keras.layers.Input(\n    shape=(1,),\n    name='customer_id_input',\n    dtype=tf.string)\n# Use the Hashing layer to hash the values to the range [0, 64]\nhasher = tf.keras.layers.Hashing(num_bins=64, salt=1337, name='customer_id_hasher')\n\n# Use the CategoryEncoding layer to multi-hot encode the hashed values\n# encoder = tf.keras.layers.IntegerLookup(max_tokens=64, output_mode=\"int\", name='customer_id_category_encoding')\n# encoded_data = encoder(hasher(x['customer_id'].values))\nencoded_data = hasher(train_data['customer_id'])","metadata":{"execution":{"iopub.status.busy":"2022-04-17T20:13:38.120591Z","iopub.execute_input":"2022-04-17T20:13:38.121084Z","iopub.status.idle":"2022-04-17T20:13:38.233957Z","shell.execute_reply.started":"2022-04-17T20:13:38.121052Z","shell.execute_reply":"2022-04-17T20:13:38.233288Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"encoded_data.numpy().shape","metadata":{"execution":{"iopub.status.busy":"2022-04-17T20:13:42.537077Z","iopub.execute_input":"2022-04-17T20:13:42.537387Z","iopub.status.idle":"2022-04-17T20:13:42.542476Z","shell.execute_reply.started":"2022-04-17T20:13:42.537351Z","shell.execute_reply":"2022-04-17T20:13:42.541819Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"np.unique([len(i) for i in train_data['article_id']], return_counts=True)","metadata":{"execution":{"iopub.status.busy":"2022-04-17T20:13:43.825624Z","iopub.execute_input":"2022-04-17T20:13:43.825927Z","iopub.status.idle":"2022-04-17T20:13:43.836805Z","shell.execute_reply.started":"2022-04-17T20:13:43.825894Z","shell.execute_reply":"2022-04-17T20:13:43.835757Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Hasing processing --- array dimensions\n\ninput_layer = tf.keras.layers.Input(\n    shape=(None, None),\n    name='article_id_input',\n    dtype=tf.string)\nhasher = tf.keras.layers.Hashing(num_bins=64, mask_value=0, name='article_id_hasher')\nencoded_data = hasher(train_data['article_id'])","metadata":{"execution":{"iopub.status.busy":"2022-04-17T20:14:23.412441Z","iopub.execute_input":"2022-04-17T20:14:23.412767Z","iopub.status.idle":"2022-04-17T20:14:29.978857Z","shell.execute_reply.started":"2022-04-17T20:14:23.412722Z","shell.execute_reply":"2022-04-17T20:14:29.977857Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"hasher([[0,0,0,0,1,1,1,1], [0,0,0,0,1,1,1,1], [0,0,0,0,1,1,1,1]])","metadata":{"execution":{"iopub.status.busy":"2022-04-17T20:15:09.970774Z","iopub.execute_input":"2022-04-17T20:15:09.971048Z","iopub.status.idle":"2022-04-17T20:15:09.983514Z","shell.execute_reply.started":"2022-04-17T20:15:09.97102Z","shell.execute_reply":"2022-04-17T20:15:09.982472Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"encoded_data","metadata":{"execution":{"iopub.status.busy":"2022-04-17T20:19:15.966586Z","iopub.execute_input":"2022-04-17T20:19:15.967051Z","iopub.status.idle":"2022-04-17T20:19:15.972674Z","shell.execute_reply.started":"2022-04-17T20:19:15.966997Z","shell.execute_reply":"2022-04-17T20:19:15.972132Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data['articles']['product_group_name'].unique(), data['articles']['product_group_name'].nunique()","metadata":{"execution":{"iopub.status.busy":"2022-04-17T20:23:46.527451Z","iopub.execute_input":"2022-04-17T20:23:46.528035Z","iopub.status.idle":"2022-04-17T20:23:46.555031Z","shell.execute_reply.started":"2022-04-17T20:23:46.527982Z","shell.execute_reply":"2022-04-17T20:23:46.554126Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# String processing\ntrain_data_sample = data['articles']['product_group_name']\n\ninput_layer = tf.keras.layers.Input(\n    shape=1,\n    name='product_group_name_input',\n    dtype=tf.string)\n\nl2 = tf.keras.layers.StringLookup(max_tokens=None, num_oov_indices=1, output_mode='int', vocabulary=data['articles']['product_group_name'].unique())","metadata":{"execution":{"iopub.status.busy":"2022-04-17T20:31:45.977306Z","iopub.execute_input":"2022-04-17T20:31:45.977747Z","iopub.status.idle":"2022-04-17T20:31:45.998508Z","shell.execute_reply.started":"2022-04-17T20:31:45.977717Z","shell.execute_reply":"2022-04-17T20:31:45.997462Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"l2(data['articles']['product_group_name'].values)","metadata":{"execution":{"iopub.status.busy":"2022-04-17T20:31:50.958168Z","iopub.execute_input":"2022-04-17T20:31:50.958637Z","iopub.status.idle":"2022-04-17T20:31:50.975674Z","shell.execute_reply.started":"2022-04-17T20:31:50.958603Z","shell.execute_reply":"2022-04-17T20:31:50.974429Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"l2([['a', 'b', 'Accessories'], ['a', 'b', 'Accessories']])","metadata":{"execution":{"iopub.status.busy":"2022-04-17T20:31:54.71598Z","iopub.execute_input":"2022-04-17T20:31:54.716357Z","iopub.status.idle":"2022-04-17T20:31:54.726107Z","shell.execute_reply.started":"2022-04-17T20:31:54.716316Z","shell.execute_reply":"2022-04-17T20:31:54.725201Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### numerical processing","metadata":{}},{"cell_type":"code","source":"np.unique(data['customers']['age'], return_counts=True)","metadata":{"execution":{"iopub.status.busy":"2022-04-17T20:41:59.818514Z","iopub.execute_input":"2022-04-17T20:41:59.819048Z","iopub.status.idle":"2022-04-17T20:41:59.909158Z","shell.execute_reply.started":"2022-04-17T20:41:59.819013Z","shell.execute_reply":"2022-04-17T20:41:59.908327Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x = data['customers']['age'].values\nn = Normalization(axis=None)\nn.adapt(x)","metadata":{"execution":{"iopub.status.busy":"2022-04-17T20:50:26.414066Z","iopub.execute_input":"2022-04-17T20:50:26.414833Z","iopub.status.idle":"2022-04-17T20:50:48.323295Z","shell.execute_reply.started":"2022-04-17T20:50:26.414783Z","shell.execute_reply":"2022-04-17T20:50:48.322318Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"n([16., 17., 18., 19., 20., 21., 22., 23., 24., 25., 26., 27., 28.,\n        29., 30., 31., 32., 33., 34., 35., 36., 37., 38., 39., 40., 41.,\n        42., 43., 44., 45., 46., 47., 48., 49., 50., 51., 52., 53., 54.,\n        55., 56., 57., 58., 59., 60., 61., 62., 63., 64., 65., 66., 67.,\n        68., 69., 70., 71., 72., 73., 74., 75., 76., 77., 78., 79., 80.,\n        81., 82., 83., 84., 85., 86., 87., 88., 89., 90., 91., 92., 93.,\n        94., 95., 96., 97., 98., 99.])","metadata":{"execution":{"iopub.status.busy":"2022-04-17T20:51:27.46137Z","iopub.execute_input":"2022-04-17T20:51:27.461685Z","iopub.status.idle":"2022-04-17T20:51:27.486029Z","shell.execute_reply.started":"2022-04-17T20:51:27.461644Z","shell.execute_reply":"2022-04-17T20:51:27.484704Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"d = Discretization(bin_boundaries=[18, 21, 25, 30, 35, 40 , 45, 50, 55, 60])\nd([16., 17., 18., 19., 20., 21., 22., 23., 24., 25., 26., 27., 28.,\n        29., 30., 31., 32., 33., 34., 35., 36., 37., 38., 39., 40., 41.,\n        42., 43., 44., 45., 46., 47., 48., 49., 50., 51., 52., 53., 54.,\n        55., 56., 57., 58., 59., 60., 61., 62., 63., 64., 65., 66., 67.,\n        68., 69., 70., 71., 72., 73., 74., 75., 76., 77., 78., 79., 80.,\n        81., 82., 83., 84., 85., 86., 87., 88., 89., 90., 91., 92., 93.,\n        94., 95., 96., 97., 98., 99.])","metadata":{"execution":{"iopub.status.busy":"2022-04-17T20:56:24.941694Z","iopub.execute_input":"2022-04-17T20:56:24.942025Z","iopub.status.idle":"2022-04-17T20:56:24.964263Z","shell.execute_reply.started":"2022-04-17T20:56:24.941986Z","shell.execute_reply":"2022-04-17T20:56:24.963412Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"d = Discretization(num_bins=10)\nd.adapt(data['customers']['age'].values)","metadata":{"execution":{"iopub.status.busy":"2022-04-17T21:00:01.851015Z","iopub.execute_input":"2022-04-17T21:00:01.85133Z","iopub.status.idle":"2022-04-17T21:00:42.98038Z","shell.execute_reply.started":"2022-04-17T21:00:01.851292Z","shell.execute_reply":"2022-04-17T21:00:42.97947Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"d([[16., 17., 18., 19.], [20., 21., 22., 23.], [24., 25., 26., 27.], [96., 97., 98., 99.]])","metadata":{"execution":{"iopub.status.busy":"2022-04-17T21:01:09.564776Z","iopub.execute_input":"2022-04-17T21:01:09.565833Z","iopub.status.idle":"2022-04-17T21:01:09.575033Z","shell.execute_reply.started":"2022-04-17T21:01:09.565762Z","shell.execute_reply":"2022-04-17T21:01:09.574257Z"},"trusted":true},"execution_count":null,"outputs":[]}]}