{"cells":[
 {
  "cell_type": "code",
  "execution_count": null,
  "metadata": {
   "collapsed": false
  },
  "outputs": [],
  "source": "import pickle\n\nimport numpy as np\nimport pandas as pd\n\nfrom csv import DictReader\nfrom math import sqrt, log, expm1\nfrom datetime import datetime\n\n'''\nmin/max for training data (test data is within the same bounds bit-wise)\n\nSemana 3 9\nAgencia_ID 1110 25759\nCanal_ID 1 11\nRuta_SAK 1 9991\nCliente_ID 26 2015152015\nProducto_ID 41 49997\nVenta_uni_hoy 0 7200\nVenta_hoy 0.0 647360.0\nDev_uni_proxima 0 250000\nDev_proxima 0.0 130760.0\nDemanda_uni_equil 0 5000\n'''\n\n# Define size limits for each field to save memory\ndtypes_test = {'Semana': np.int8, 'Agencia_ID': np.int16, 'Canal_ID': np.int8, 'Producto_ID': np.uint16}\n\n# python 3.5 version: {**dtypes_test, **{'Venta_uni_hoy': np.uint16, 'Dev_uni_proxima': np.int32, 'Demanda_uni_equil': np.int16}}\ndtypes_train = {'Semana': np.int8, 'Agencia_ID': np.int16, 'Canal_ID': np.int8, 'Producto_ID': np.uint16,\n               'Venta_uni_hoy': np.uint16, 'Dev_uni_proxima': np.int32, 'Demanda_uni_equil': np.int16}\n\n# Now load train+test data\ndatadir = '../input/'\ndf_train = pd.read_csv(datadir + 'train.csv', dtype = dtypes_train, usecols = ['Producto_ID', 'Ruta_SAK', 'Agencia_ID', 'Cliente_ID', 'Demanda_uni_equil'])\ndf_test = pd.read_csv(datadir + 'test.csv', dtype = dtypes_test)\n\ndf_train['log_demand'] = np.log1p(df_train.Demanda_uni_equil)\n\n# Compute the three log means - the processing code works faster (less slowly?) if they're converted to Dictionaries.\ndemand_prod = (df_train.groupby(['Producto_ID']))['log_demand'].mean().to_dict()\n#demand_prod_ruta = (df_train.groupby(['Producto_ID', 'Ruta_SAK']))['log_demand'].mean().to_dict()\n#demand_prod_cli_age = (df_train.groupby(['Producto_ID', 'Cliente_ID', 'Agencia_ID']))['log_demand'].mean().to_dict()\n\nsubmission = np.zeros(len(df_test))\n\nk = 0\n\n# We need to handle one product at a time, otherwise the dictionaries get too large...\n\ndef process_product(product_id, sub):\n    global k\n    \n    df_train_subset = df_train[df_train['Producto_ID'] == product_id]\n    df_test_subset = df_test[df_test['Producto_ID'] == product_id]\n    \n    demand_prod_ruta = (df_train_subset.groupby(['Producto_ID', 'Ruta_SAK']))['log_demand'].mean().to_dict()\n    demand_prod_cli_age = (df_train_subset.groupby(['Producto_ID', 'Cliente_ID', 'Agencia_ID']))['log_demand'].mean().to_dict()\n    \n    df_test_p = df_test_subset['Producto_ID']\n\n    df_test_pr = df_test_subset[['Producto_ID', 'Ruta_SAK']]\n    df_test_l_pr = list(df_test_pr.itertuples(index=False, name=None))\n\n    df_test_pca = df_test_subset[['Producto_ID', 'Cliente_ID', 'Agencia_ID']]\n    df_test_l_pca = list(df_test_pca.itertuples(index=False, name=None))\n    \n    output = []\n\n    # make a meta-tuple of each of the tuples used to do log-mean lookups\n    for z in zip(df_test_subset.id, df_test_p, df_test_l_pr, df_test_l_pca):\n\n        # Work in order of preference.  With straight dicts this is faster than try/except\n        if z[3] in demand_prod_cli_age:\n            o = demand_prod_cli_age[z[3]]\n        elif z[2] in demand_prod_ruta:\n            o = demand_prod_ruta[z[2]]\n        elif z[1] in demand_prod:\n            o = demand_prod[z[1]]\n        else:\n            o = 1\n            \n        sub[z[0]] = np.expm1(o) * .9\n\nfor p in df_test.Producto_ID.unique():\n    process_product(p, submission)            \n\n# Now output\ndf_test['Demanda_uni_equil'] = submission\n\ndf_submit = df_test[['id', 'Demanda_uni_equil']]\ndf_submit = df_submit.set_index('id')\ndf_submit.to_csv('meantest2a.csv')"
 }
],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"}}, "nbformat": 4, "nbformat_minor": 0}