{"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":"markdown","source":"# H&M Sales and Customers analysis","metadata":{}},{"cell_type":"markdown","source":"The following project aims to analyze the sales and customers data provided by H&M.<br>\nThe project is structred as follows:\n- Transactions analysis:\n    - Q1 - Which are the TOP 100 articles in terms of sold quantity?\n    - Q2 - Are there articles that have been sold only once?\n    - Q3 - Which are the TOP 100 articles that generated most earnings for the company?\n    - Q4 - Which are articles that generated lower earnings for the company? \n\n- Customer Analysis:\n    - Q5 - Which age group purchase more articles?\n    - Q6 - Which age group generates more earnings for the company?\n    - Q7 - Do active customers on the fashion news purchase more articles?\n    - Q8 - Does the club member status influence the purchased quantity of articles?","metadata":{}},{"cell_type":"markdown","source":"# **Main results summary dashboard:**","metadata":{}},{"cell_type":"markdown","source":"<img src=\"https://i.imgur.com/8sn0J8D.png\">","metadata":{}},{"cell_type":"markdown","source":"**Among the TOP 100 of solds products:**\n- Almost 30% of sold products are trousers\n- 38% is Ladieswear\n- 30% is Lingeries/Tights\n- Over 70% are black colored\n- Almost 40% are related to lower body","metadata":{}},{"cell_type":"markdown","source":"<img src=\"https://i.imgur.com/TG95am4.png\">","metadata":{}},{"cell_type":"markdown","source":"**Among the TOP 100 products in terms of earnings:**\n- Over 60% of the total earnings are generated by selling trousers\n- Around 50% of these products belonsg to the DIVIDED collection (a H&M teenage collection)\n- 37% of the products are from the Ladieswear line\n- 55% of the products are black\n- 66.2% of the products are related to lower body\n","metadata":{}},{"cell_type":"markdown","source":"<img src=\"https://i.imgur.com/5SZMW8h.png\">","metadata":{}},{"cell_type":"markdown","source":"Insights:\n- Customers in the range 20-30 are responsible for more than 42% of the total purchased products.\n- Customers in the range 16-20. 60-70 and 70+ are responsible for the 8% of the total purchased products\n- Customers in the range 30-40, 40-50 and 50-60 are responsible for 16% of purchased quantity each.\n\n**Indeed a very similar situation to the purchases quantity can be found in the earnings analysis, since customers who buys more, on average leads to higher earnings for the company. <br>\nThe age group 20-30 is by far responsible for the highest earnings for the company (41.9% of total earnings).**","metadata":{}},{"cell_type":"markdown","source":"<img src=\"https://i.imgur.com/TSALUiK.png\">","metadata":{}},{"cell_type":"markdown","source":"We can see that **customers in the range 20-30 and 30-40 have the lowest percentage of fashion news frequency, while being the groups which buy the most**.<br>\nMoreover, **the frequency of customer that regulary check fashion news starts increasing from the range 40-50, with a peak value of 43.7% of regular/active users for customers in the range 70+ years old**. This means that **checking fashion news seems to be more effective for older customers, who still represent a small percentage of total sold products, while younger customers do not need to check the news to buy new products**. <br>\n**It could be effective for the company to invite younger customers (range 20-40) to check the news more frequently in order to increase the sold items.**","metadata":{}},{"cell_type":"markdown","source":"<img src=\"https://i.imgur.com/ifAvKwO.png\" width=\"600px\">","metadata":{}},{"cell_type":"markdown","source":"**This plots shows that the average purchased quantity differs a lot among the categories**. <br>\nIn particular, **customers belonging to the ACTIVE clubs, purchase more products than other categories, while those in the \"pre-create\" category purchaes on average less than a third of third of active customers**.\n","metadata":{}},{"cell_type":"markdown","source":"### Import libraries","metadata":{}},{"cell_type":"code","source":"import numpy as np \nimport pandas as pd\nfrom pandasql import sqldf\n\nimport matplotlib.pyplot as plt\nimport seaborn as sns\n\nplt.style.use('seaborn-white')\nsns.set_style(\"whitegrid\")\nsns.despine()\nplt.rc(\"figure\", autolayout=True)\nplt.rc(\"axes\", labelweight=\"bold\", labelsize=\"large\", titleweight=\"bold\", titlesize=14, titlepad=10)\n\nimport matplotlib as mpl\n\nmpl.rcParams['axes.spines.left'] = False\nmpl.rcParams['axes.spines.right'] = False\nmpl.rcParams['axes.spines.top'] = False\nmpl.rcParams['axes.spines.bottom'] = False\nplt.rcParams[\"font.weight\"] = \"bold\"\nplt.rcParams[\"axes.labelweight\"] = \"bold\"","metadata":{"execution":{"iopub.status.busy":"2022-02-26T14:16:51.466726Z","iopub.execute_input":"2022-02-26T14:16:51.467347Z","iopub.status.idle":"2022-02-26T14:16:52.683977Z","shell.execute_reply.started":"2022-02-26T14:16:51.467243Z","shell.execute_reply":"2022-02-26T14:16:52.683049Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Data import","metadata":{}},{"cell_type":"markdown","source":"First, we import the data.","metadata":{}},{"cell_type":"code","source":"df_a = pd.read_csv(\"/kaggle/input/h-and-m-personalized-fashion-recommendations/articles.csv\")\ndf_t = pd.read_csv(\"/kaggle/input/h-and-m-personalized-fashion-recommendations/transactions_train.csv\")\ndf_c = pd.read_csv(\"/kaggle/input/h-and-m-personalized-fashion-recommendations/customers.csv\")","metadata":{"execution":{"iopub.status.busy":"2022-02-26T14:16:52.685421Z","iopub.execute_input":"2022-02-26T14:16:52.685659Z","iopub.status.idle":"2022-02-26T14:18:09.040827Z","shell.execute_reply.started":"2022-02-26T14:16:52.685631Z","shell.execute_reply":"2022-02-26T14:18:09.039815Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Articles dataframe analysis","metadata":{}},{"cell_type":"code","source":"df_a.head(1)","metadata":{"execution":{"iopub.status.busy":"2022-02-26T14:18:09.042191Z","iopub.execute_input":"2022-02-26T14:18:09.042459Z","iopub.status.idle":"2022-02-26T14:18:09.076544Z","shell.execute_reply.started":"2022-02-26T14:18:09.042426Z","shell.execute_reply":"2022-02-26T14:18:09.075950Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_a.columns","metadata":{"execution":{"iopub.status.busy":"2022-02-26T14:18:09.078275Z","iopub.execute_input":"2022-02-26T14:18:09.078987Z","iopub.status.idle":"2022-02-26T14:18:09.085440Z","shell.execute_reply.started":"2022-02-26T14:18:09.078944Z","shell.execute_reply":"2022-02-26T14:18:09.084415Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f\"The dataframe articles has {len(df_a)} rows\")","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-02-26T14:18:09.093422Z","iopub.execute_input":"2022-02-26T14:18:09.093714Z","iopub.status.idle":"2022-02-26T14:18:09.100775Z","shell.execute_reply.started":"2022-02-26T14:18:09.093677Z","shell.execute_reply":"2022-02-26T14:18:09.099848Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The \"articles\" dataframe has 25 columns and more than 100k rows.<br>\nFor our our analysis we will just select the following columns: \n- article_id\n- prod_name\n- product_type_name\n- product_group_name\n- colour_group_name\n- index_name\n\nBy considering only these columns we can also save lots of memory.","metadata":{}},{"cell_type":"markdown","source":"To filter the columns, we will use SQL like code through SQL-DF library.","metadata":{}},{"cell_type":"code","source":"df_a = sqldf(\"\"\"SELECT article_id, prod_name, product_type_name, product_group_name, colour_group_name, index_name\n            FROM df_a\n            \"\"\")","metadata":{"execution":{"iopub.status.busy":"2022-02-26T14:18:09.102415Z","iopub.execute_input":"2022-02-26T14:18:09.102779Z","iopub.status.idle":"2022-02-26T14:18:16.359888Z","shell.execute_reply.started":"2022-02-26T14:18:09.102743Z","shell.execute_reply":"2022-02-26T14:18:16.358662Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_a.head()","metadata":{"execution":{"iopub.status.busy":"2022-02-26T14:18:16.361266Z","iopub.execute_input":"2022-02-26T14:18:16.361519Z","iopub.status.idle":"2022-02-26T14:18:16.375944Z","shell.execute_reply.started":"2022-02-26T14:18:16.361486Z","shell.execute_reply":"2022-02-26T14:18:16.374957Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Transactions dataframe analysis","metadata":{}},{"cell_type":"code","source":"df_t.head(1)","metadata":{"execution":{"iopub.status.busy":"2022-02-26T14:18:16.380426Z","iopub.execute_input":"2022-02-26T14:18:16.380803Z","iopub.status.idle":"2022-02-26T14:18:16.395337Z","shell.execute_reply.started":"2022-02-26T14:18:16.380752Z","shell.execute_reply":"2022-02-26T14:18:16.394554Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_t.columns","metadata":{"execution":{"iopub.status.busy":"2022-02-26T14:18:16.396246Z","iopub.execute_input":"2022-02-26T14:18:16.396507Z","iopub.status.idle":"2022-02-26T14:18:16.410713Z","shell.execute_reply.started":"2022-02-26T14:18:16.396478Z","shell.execute_reply":"2022-02-26T14:18:16.409632Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f\"The dataframe Transactions has {len(df_t)} rows\")","metadata":{"execution":{"iopub.status.busy":"2022-02-26T14:18:16.412824Z","iopub.execute_input":"2022-02-26T14:18:16.413861Z","iopub.status.idle":"2022-02-26T14:18:16.422507Z","shell.execute_reply.started":"2022-02-26T14:18:16.413810Z","shell.execute_reply":"2022-02-26T14:18:16.421531Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The Transactions dataframe has more than 31 million rows: in order to save memory, we decide to drop some columns and keep only \"customer_id\", \"article_id\", \"price\".","metadata":{}},{"cell_type":"code","source":"df_t = df_t[[\"customer_id\", \"article_id\", \"price\"]]","metadata":{"execution":{"iopub.status.busy":"2022-02-26T14:18:16.424369Z","iopub.execute_input":"2022-02-26T14:18:16.424813Z","iopub.status.idle":"2022-02-26T14:18:17.022354Z","shell.execute_reply.started":"2022-02-26T14:18:16.424673Z","shell.execute_reply":"2022-02-26T14:18:17.021668Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"In the following we will focus in the analysis of the transaction dataframe, in order to discover the most and least sold products.","metadata":{"execution":{"iopub.status.busy":"2022-02-20T17:46:34.27739Z","iopub.execute_input":"2022-02-20T17:46:34.277701Z","iopub.status.idle":"2022-02-20T17:46:34.28398Z","shell.execute_reply.started":"2022-02-20T17:46:34.277671Z","shell.execute_reply":"2022-02-20T17:46:34.282952Z"}}},{"cell_type":"markdown","source":"# Transactions analysis ","metadata":{}},{"cell_type":"markdown","source":"First, we extract the quantities sold per article using the value counts method on the \"article_id\" column of the transaction dataframe.","metadata":{}},{"cell_type":"code","source":"df_sold_qty = df_t[\"article_id\"].value_counts()\ndf_sold_qty","metadata":{"execution":{"iopub.status.busy":"2022-02-26T14:18:17.023430Z","iopub.execute_input":"2022-02-26T14:18:17.023796Z","iopub.status.idle":"2022-02-26T14:18:18.472638Z","shell.execute_reply.started":"2022-02-26T14:18:17.023767Z","shell.execute_reply":"2022-02-26T14:18:18.471740Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Then we create a dataframe based on this pandas series: this is necessary since later this dataframe will be joined with the \"article\" dataframe by the article_id column, in order to get informtions on the products.**","metadata":{}},{"cell_type":"code","source":"df_sold_qty=df_sold_qty.reset_index()\ndf_sold_qty.rename(columns = {\"article_id\":\"sold_qty\",\"index\":\"article_id\"}, inplace=True)\ndf_sold_qty.head()","metadata":{"execution":{"iopub.status.busy":"2022-02-26T14:18:18.473865Z","iopub.execute_input":"2022-02-26T14:18:18.474137Z","iopub.status.idle":"2022-02-26T14:18:18.488695Z","shell.execute_reply.started":"2022-02-26T14:18:18.474106Z","shell.execute_reply":"2022-02-26T14:18:18.487750Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Then we can get some summary statistics about the sold quantities by calling the describe method on the \"sold_qty\" column:","metadata":{}},{"cell_type":"code","source":"df_sold_qty[\"sold_qty\"].describe()","metadata":{"execution":{"iopub.status.busy":"2022-02-26T14:18:18.489981Z","iopub.execute_input":"2022-02-26T14:18:18.490365Z","iopub.status.idle":"2022-02-26T14:18:18.514995Z","shell.execute_reply.started":"2022-02-26T14:18:18.490330Z","shell.execute_reply":"2022-02-26T14:18:18.514285Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Summary statistics on the sold quantities:\n- there are 105000 different articles in the transactions.\n- There are items which have been sold only once\n- 25% of sold products, have been sold 14 or less times\n- 50% were sold 65 or less times\n- 75% were sold 286 or less times,\n- The most sold item have been sold 50287 times.","metadata":{}},{"cell_type":"markdown","source":"**We can expect a very skewed distribution of this variable, which can be checked by plotting the variable:**","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(12,4))\nplt.title(\"Sold Quantity KDE plot\")\nsns.kdeplot(df_sold_qty[\"sold_qty\"])\nplt.xlabel(\"Sold Quantity\")\nplt.show()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-02-26T14:18:18.516258Z","iopub.execute_input":"2022-02-26T14:18:18.516619Z","iopub.status.idle":"2022-02-26T14:18:19.304155Z","shell.execute_reply.started":"2022-02-26T14:18:18.516590Z","shell.execute_reply":"2022-02-26T14:18:19.303183Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Indeed, the distribution is heavily right skewed.**","metadata":{}},{"cell_type":"markdown","source":"It could be also interesting to check high quantiles of the distribution.","metadata":{}},{"cell_type":"code","source":"df_sold_qty[\"sold_qty\"].quantile([0.90,0.95,0.99,0.999])","metadata":{"execution":{"iopub.status.busy":"2022-02-26T14:18:19.305467Z","iopub.execute_input":"2022-02-26T14:18:19.306243Z","iopub.status.idle":"2022-02-26T14:18:19.318050Z","shell.execute_reply.started":"2022-02-26T14:18:19.306177Z","shell.execute_reply":"2022-02-26T14:18:19.317157Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The quantile analysis can give us the following insights: \n- 90% of the articles have been sold 793 or less times\n- 95% of the articles have been sold 1318 or less times\n- 99% of the articles have been sold 3185 or less times\n\n**This shows that there is a very small minority of items that sold more than 10k times (just the 0.001%), highlighting the skewness nature of the distribution.**","metadata":{}},{"cell_type":"markdown","source":"# Q1 - Which are the TOP 100 articles in terms of sold quantity?","metadata":{"execution":{"iopub.status.busy":"2022-02-21T08:43:45.895313Z","iopub.execute_input":"2022-02-21T08:43:45.895583Z","iopub.status.idle":"2022-02-21T08:43:45.913209Z","shell.execute_reply.started":"2022-02-21T08:43:45.895554Z","shell.execute_reply":"2022-02-21T08:43:45.912667Z"}}},{"cell_type":"markdown","source":"We can simply extract the most 100 sold items from the dataframe \"df_sold_qty\" by taking the first 100 rows.","metadata":{}},{"cell_type":"code","source":"top_100_sold = df_sold_qty.iloc[:100]\ntop_100_sold.head()","metadata":{"execution":{"iopub.status.busy":"2022-02-26T14:18:19.319247Z","iopub.execute_input":"2022-02-26T14:18:19.319490Z","iopub.status.idle":"2022-02-26T14:18:19.334429Z","shell.execute_reply.started":"2022-02-26T14:18:19.319461Z","shell.execute_reply":"2022-02-26T14:18:19.333791Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Then we join this dataframe with the articles dataframe (df_a) by the \"article_id\" column in order to get more details about each article.","metadata":{}},{"cell_type":"code","source":"top_100_details = sqldf(\"\"\"SELECT *\n        FROM top_100_sold t\n        INNER JOIN df_a a\n        on t.article_id = a.article_id\n    \"\"\")","metadata":{"execution":{"iopub.status.busy":"2022-02-26T14:18:19.335621Z","iopub.execute_input":"2022-02-26T14:18:19.336196Z","iopub.status.idle":"2022-02-26T14:18:21.548617Z","shell.execute_reply.started":"2022-02-26T14:18:19.336153Z","shell.execute_reply":"2022-02-26T14:18:21.547620Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"top_100_details.head()","metadata":{"execution":{"iopub.status.busy":"2022-02-26T14:18:21.550035Z","iopub.execute_input":"2022-02-26T14:18:21.550381Z","iopub.status.idle":"2022-02-26T14:18:21.565754Z","shell.execute_reply.started":"2022-02-26T14:18:21.550338Z","shell.execute_reply":"2022-02-26T14:18:21.564490Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(10,8))\nplt.title(\"TOP 30 most sold products\", fontsize=33, fontweight=\"bold\")\nno=30\ng = sns.barplot(y=\"prod_name\", x=\"sold_qty(%)\", data=top_100_details.iloc[:no].groupby(\"prod_name\")[\"sold_qty\"].sum() \\\n            .transform(lambda x: (x / x.sum() * 100)).rename('sold_qty(%)').reset_index().sort_values(by=\"sold_qty(%)\", ascending=False), \\\n            palette=\"mako\", ci=False)\nfor container in g.containers:\n    g.bar_label(container, padding = 5, fmt='%.1f', fontsize=12)\nplt.xlabel(\"Sold Quantity (%)\", size=25, fontweight=\"bold\")\nplt.ylabel(\"\")\nplt.grid(axis=\"x\",color = 'grey', linestyle = '--', linewidth = 1.5)\nplt.show()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-02-26T14:18:21.567452Z","iopub.execute_input":"2022-02-26T14:18:21.567974Z","iopub.status.idle":"2022-02-26T14:18:22.392086Z","shell.execute_reply.started":"2022-02-26T14:18:21.567921Z","shell.execute_reply":"2022-02-26T14:18:22.391045Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We decided to plot only the TOP 30 of articles since including the TOP 50 or 100 product names would hve lead to a very big plot !\nIndeed we can see that among the TOP 100 sold articles:\n- The trousers \"Jade HW Skinny Denim TRS \" is responsible for almost 19% of all sold products.\n- the TOP 4 of most sold items, is responsible for almost 40% of the TOP 100 sold products.","metadata":{}},{"cell_type":"markdown","source":"For what concerns other product characteristics (besides the product name), we can obtain very effective plots even if we consider 100 products:","metadata":{}},{"cell_type":"code","source":"fig, ax = plt.subplots(2,2, figsize=(13,9.5))\nplt.suptitle(\"TOP 100 most sold products characteristics\", fontweight=\"bold\",fontsize=30)\n\nno=100\n\ng = sns.barplot(y=\"product_type_name\", x=\"sold_qty(%)\", data=top_100_details.iloc[:no].groupby(\"product_type_name\")[\"sold_qty\"].sum() \\\n            .transform(lambda x: (x / x.sum() * 100)).rename('sold_qty(%)').reset_index().sort_values(by=\"sold_qty(%)\", ascending=False), \\\n            ax=ax[0,0],palette=\"mako\", ci=False)\nfor container in g.containers:\n    g.bar_label(container, padding = 5, fmt='%.1f', fontsize=12, color=\"black\")\nax[0,0].set_ylabel(\"\")\nax[0,0].set_xlabel(\"Sold Quantity (%)\", size=22, fontweight=\"bold\")\nax[0,0].set_title(\"Product Type\",fontweight=\"bold\",fontsize=28)\nax[0,0].grid(axis=\"x\",color = 'grey', linestyle = '--', linewidth = 1.5)\n\ng = sns.barplot(y=\"index_name\", x=\"sold_qty(%)\", data=top_100_details.iloc[:no].groupby(\"index_name\")[\"sold_qty\"].sum() \\\n            .transform(lambda x: (x / x.sum() * 100)).rename('sold_qty(%)').reset_index().sort_values(by=\"sold_qty(%)\", ascending=False), \\\n            ax=ax[0,1],palette=\"viridis\", ci=False)\nfor container in g.containers:\n    g.bar_label(container, padding = 5, fmt='%.1f', fontsize=15, color=\"black\")\nax[0,1].set_ylabel(\"\")\nax[0,1].set_xlabel(\"Sold Quantity (%)\", size=22, fontweight=\"bold\")\nax[0,1].set_title(\"Index\",fontweight=\"bold\",fontsize=28)\nax[0,1].grid(axis=\"x\",color = 'grey', linestyle = '--', linewidth = 1.5)\n\ng = sns.barplot(y=\"colour_group_name\", x=\"sold_qty(%)\", data=top_100_details.iloc[:no].groupby(\"colour_group_name\")[\"sold_qty\"].sum() \\\n            .transform(lambda x: (x / x.sum() * 100)).rename('sold_qty(%)').reset_index().sort_values(by=\"sold_qty(%)\", ascending=False), \\\n            ax=ax[1,0],palette=\"mako\", ci=False)\nfor container in g.containers:\n    g.bar_label(container, padding = 5, fmt='%.1f', fontsize=15, color=\"black\")\nax[1,0].set_ylabel(\"\")\nax[1,0].set_xlabel(\"Sold Quantity (%)\", size=22, fontweight=\"bold\")\nax[1,0].set_title(\"Colour Group\",fontweight=\"bold\",fontsize=28)\nax[1,0].grid(axis=\"x\",color = 'grey', linestyle = '--', linewidth = 1.5)\n\ng = sns.barplot(y=\"product_group_name\", x=\"sold_qty(%)\", data=top_100_details.iloc[:no].groupby(\"product_group_name\")[\"sold_qty\"].sum() \\\n            .transform(lambda x: (x / x.sum() * 100)).rename('sold_qty(%)').reset_index().sort_values(by=\"sold_qty(%)\", ascending=False), \\\n            ax=ax[1,1],palette=\"Reds_r\", ci=False)\nfor container in g.containers:\n    g.bar_label(container, padding = 5, fmt='%.1f', fontsize=15, color=\"black\")\nax[1,1].set_ylabel(\"\")\nax[1,1].set_xlabel(\"Sold Quantity (%)\", size=22, fontweight=\"bold\")\nax[1,1].set_title(\"Product Group\",fontweight=\"bold\",fontsize=28)\nax[1,1].grid(axis=\"x\",color = 'grey', linestyle = '--', linewidth = 1.5)\nfig.tight_layout()\n\nplt.show() ","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-02-26T14:18:22.393592Z","iopub.execute_input":"2022-02-26T14:18:22.394523Z","iopub.status.idle":"2022-02-26T14:18:24.219856Z","shell.execute_reply.started":"2022-02-26T14:18:22.394463Z","shell.execute_reply":"2022-02-26T14:18:24.219132Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Among the TOP 100 of solds products:\n- Almost 30% of sold products are trousers\n- 38% is Ladieswear\n- 30% is Lingeries/Tights\n- Over 70% are black colored\n- Almost 40% are related to lower body","metadata":{}},{"cell_type":"markdown","source":"# Q2 - Are there articles that have been sold only once?","metadata":{}},{"cell_type":"markdown","source":"As we observed in the previous analysis, there are items that sold only once. We will investigate about these products.","metadata":{}},{"cell_type":"code","source":"df_sold_qty[\"sold_qty\"].where(lambda x: x==1).dropna() #top 15% products","metadata":{"execution":{"iopub.status.busy":"2022-02-26T14:18:24.221000Z","iopub.execute_input":"2022-02-26T14:18:24.221623Z","iopub.status.idle":"2022-02-26T14:18:24.240599Z","shell.execute_reply.started":"2022-02-26T14:18:24.221590Z","shell.execute_reply":"2022-02-26T14:18:24.239960Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Almost 5000 different items have been sold just once. <br>\nSince in the \"Transactions\" dataframe there are around 100000 different items, this means that among the transactions, almost 5% of the products  have only been sold once.**","metadata":{}},{"cell_type":"markdown","source":"Then we can extract these items from the \"df_sold_qty\" dataframe by taking the last 4491 values. ( There are 4491 items that sold once)","metadata":{}},{"cell_type":"code","source":"worst_sold = df_sold_qty.tail(4491)","metadata":{"execution":{"iopub.status.busy":"2022-02-26T14:18:24.241766Z","iopub.execute_input":"2022-02-26T14:18:24.242010Z","iopub.status.idle":"2022-02-26T14:18:24.245501Z","shell.execute_reply.started":"2022-02-26T14:18:24.241982Z","shell.execute_reply":"2022-02-26T14:18:24.244958Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"And finally join this newly defined dataframe \"worst_sold\" to the articles dataframe df_a to get the articles characterisics.","metadata":{}},{"cell_type":"code","source":"worst_details = sqldf(\"\"\"SELECT *\n        FROM worst_sold t\n        INNER JOIN df_a a\n        on t.article_id = a.article_id\n    \"\"\")","metadata":{"execution":{"iopub.status.busy":"2022-02-26T14:18:24.246654Z","iopub.execute_input":"2022-02-26T14:18:24.247048Z","iopub.status.idle":"2022-02-26T14:18:26.625901Z","shell.execute_reply.started":"2022-02-26T14:18:24.247009Z","shell.execute_reply":"2022-02-26T14:18:26.625048Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, ax = plt.subplots(2,2, figsize=(19,14))\nplt.suptitle(\"Characteristic of products sold only once\", size=38, fontweight=\"bold\")\n\nno=100\n\ng = sns.barplot(y=\"product_type_name\", x=\"sold_qty(%)\", data=worst_details.iloc[:no].groupby(\"product_type_name\")[\"sold_qty\"].sum() \\\n            .transform(lambda x: (x / x.sum() * 100)).rename('sold_qty(%)').reset_index().sort_values(by=\"sold_qty(%)\", ascending=False), \\\n            ax=ax[0,0],palette=\"viridis_r\", ci=False)\nfor container in g.containers:\n    g.bar_label(container, padding = 5, fmt='%.1f', fontsize=12, color=\"black\")\nax[0,0].set_ylabel(\"\")\nax[0,0].set_xlabel(\"Sold Quantity (%)\", size=20, fontweight=\"bold\")\nax[0,0].set_title(\"Product Type\", size=25, fontweight=\"bold\")\nax[0,0].grid(axis=\"x\",color = 'grey', linestyle = '--', linewidth = 1.5)\n\ng = sns.barplot(y=\"index_name\", x=\"sold_qty(%)\", data=worst_details.iloc[:no].groupby(\"index_name\")[\"sold_qty\"].sum() \\\n            .transform(lambda x: (x / x.sum() * 100)).rename('sold_qty(%)').reset_index().sort_values(by=\"sold_qty(%)\", ascending=False), \\\n            ax=ax[0,1],palette=\"Reds_r\", ci=False)\nfor container in g.containers:\n    g.bar_label(container, padding = 5, fmt='%.1f', fontsize=15, color=\"black\")\nax[0,1].set_ylabel(\"\")\nax[0,1].set_xlabel(\"Sold Quantity (%)\", size=20, fontweight=\"bold\")\nax[0,1].set_title(\"Index\", size=25, fontweight=\"bold\")\nax[0,1].grid(axis=\"x\",color = 'grey', linestyle = '--', linewidth = 1.5)\n\ng = sns.barplot(y=\"colour_group_name\", x=\"sold_qty(%)\", data=worst_details.iloc[:no].groupby(\"colour_group_name\")[\"sold_qty\"].sum() \\\n            .transform(lambda x: (x / x.sum() * 100)).rename('sold_qty(%)').reset_index().sort_values(by=\"sold_qty(%)\", ascending=False), \\\n            ax=ax[1,0],palette=\"mako\", ci=False)\nfor container in g.containers:\n    g.bar_label(container, padding = 5, fmt='%.1f', fontsize=12, color=\"black\")\nax[1,0].set_ylabel(\"\")\nax[1,0].set_xlabel(\"Sold Quantity (%)\", size=20, fontweight=\"bold\")\nax[1,0].set_title(\"Colour Group\", size=25, fontweight=\"bold\")\nax[1,0].grid(axis=\"x\",color = 'grey', linestyle = '--', linewidth = 1.5)\n\ng = sns.barplot(y=\"product_group_name\", x=\"sold_qty(%)\", data=worst_details.iloc[:no].groupby(\"product_group_name\")[\"sold_qty\"].sum() \\\n            .transform(lambda x: (x / x.sum() * 100)).rename('sold_qty(%)').reset_index().sort_values(by=\"sold_qty(%)\", ascending=False), \\\n            ax=ax[1,1],palette=\"Blues_r\", ci=False)\nfor container in g.containers:\n    g.bar_label(container, padding = 5, fmt='%.1f', fontsize=15, color=\"black\")\nax[1,1].set_ylabel(\"\")\nax[1,1].set_xlabel(\"Sold Quantity (%)\", size=20, fontweight=\"bold\")\nax[1,1].set_title(\"Product Group\", size=25, fontweight=\"bold\")\nax[1,1].grid(axis=\"x\",color = 'grey', linestyle = '--', linewidth = 1.5)\n\nfig.tight_layout()\n\nplt.show() ","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-02-26T14:18:26.627470Z","iopub.execute_input":"2022-02-26T14:18:26.628014Z","iopub.status.idle":"2022-02-26T14:18:29.002640Z","shell.execute_reply.started":"2022-02-26T14:18:26.627973Z","shell.execute_reply":"2022-02-26T14:18:29.001664Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Insights:\n- We can see that almost 60% of only sold once items are for children.","metadata":{}},{"cell_type":"markdown","source":"# Q3 - Which are the TOP 100 articles that generated most earnings for the company?","metadata":{}},{"cell_type":"markdown","source":"After analyzing the sold quantites for each product, it can be interesting to analyze the total earnings generated by each product.<br>\n**The earnings can be calculated by multiplying the price of each product by its total sold quanity**. <br>\n*NOTE: For privacy reasons, the prices have been transformed/scaled by the creator of the dataset, and so do not represent any known currency.*","metadata":{}},{"cell_type":"markdown","source":"We will now create a new dataframe df_prices which will inlude the earnings generated by each product.","metadata":{}},{"cell_type":"code","source":"df_prices = df_t[[\"price\",\"article_id\"]].groupby(\"article_id\").sum().sort_values(by=\"price\", ascending=False)","metadata":{"execution":{"iopub.status.busy":"2022-02-26T14:18:29.009547Z","iopub.execute_input":"2022-02-26T14:18:29.010118Z","iopub.status.idle":"2022-02-26T14:18:30.713553Z","shell.execute_reply.started":"2022-02-26T14:18:29.010060Z","shell.execute_reply":"2022-02-26T14:18:30.712737Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_prices.rename(columns={\"price\":\"earning\"}, inplace=True)\ndf_prices = df_prices.reset_index()","metadata":{"execution":{"iopub.status.busy":"2022-02-26T14:18:30.714690Z","iopub.execute_input":"2022-02-26T14:18:30.714932Z","iopub.status.idle":"2022-02-26T14:18:30.721691Z","shell.execute_reply.started":"2022-02-26T14:18:30.714895Z","shell.execute_reply":"2022-02-26T14:18:30.720769Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_prices.head()","metadata":{"execution":{"iopub.status.busy":"2022-02-26T14:18:30.723236Z","iopub.execute_input":"2022-02-26T14:18:30.723498Z","iopub.status.idle":"2022-02-26T14:18:30.739648Z","shell.execute_reply.started":"2022-02-26T14:18:30.723471Z","shell.execute_reply":"2022-02-26T14:18:30.738794Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**We can see that the most earnings generated by a product is 1631**. <br>\nHow much is the total earnings?","metadata":{}},{"cell_type":"code","source":"print(\"Number of different sold articles:\",len(df_prices[\"earning\"]))\nprint(\"Total Earnings:\",df_prices[\"earning\"].sum())","metadata":{"execution":{"iopub.status.busy":"2022-02-26T14:18:30.741416Z","iopub.execute_input":"2022-02-26T14:18:30.741741Z","iopub.status.idle":"2022-02-26T14:18:30.754717Z","shell.execute_reply.started":"2022-02-26T14:18:30.741698Z","shell.execute_reply":"2022-02-26T14:18:30.753682Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for i in [10,50,100,200,300,400,1000]:\n    print(\"The TOP {} of products that generate most earnings, account for the {:.2f} % of total earnings\".format(i, df_prices[\"earning\"].iloc[:i].sum() / df_prices[\"earning\"].iloc[:].sum() * 100) ) ","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-02-26T14:18:30.755601Z","iopub.execute_input":"2022-02-26T14:18:30.755837Z","iopub.status.idle":"2022-02-26T14:18:30.770931Z","shell.execute_reply.started":"2022-02-26T14:18:30.755799Z","shell.execute_reply":"2022-02-26T14:18:30.770163Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**The TOP 100 of over 100000 products, generates around 5% of the total earnings. It can be interesting to check these products names and characteristics.**","metadata":{}},{"cell_type":"markdown","source":"So we create a new dataframe top_100_prices, where we include only the TOP 100 articles from the df_prices dataframe.","metadata":{}},{"cell_type":"code","source":"top_100_prices=df_prices.iloc[:100]","metadata":{"execution":{"iopub.status.busy":"2022-02-26T14:18:30.772048Z","iopub.execute_input":"2022-02-26T14:18:30.772725Z","iopub.status.idle":"2022-02-26T14:18:30.777806Z","shell.execute_reply.started":"2022-02-26T14:18:30.772692Z","shell.execute_reply":"2022-02-26T14:18:30.777078Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Then, as seen before, we join this new dataframe to the articles dataframe df_a to get the articles information.","metadata":{}},{"cell_type":"code","source":"top_100_price_details = sqldf(\"\"\"SELECT *\n        FROM top_100_prices t\n        INNER JOIN df_a a\n        on t.article_id = a.article_id\"\"\")","metadata":{"execution":{"iopub.status.busy":"2022-02-26T14:18:30.778963Z","iopub.execute_input":"2022-02-26T14:18:30.779312Z","iopub.status.idle":"2022-02-26T14:18:33.060009Z","shell.execute_reply.started":"2022-02-26T14:18:30.779284Z","shell.execute_reply":"2022-02-26T14:18:33.059248Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"top_100_price_details.head()","metadata":{"execution":{"iopub.status.busy":"2022-02-26T14:18:33.061288Z","iopub.execute_input":"2022-02-26T14:18:33.062193Z","iopub.status.idle":"2022-02-26T14:18:33.076246Z","shell.execute_reply.started":"2022-02-26T14:18:33.062148Z","shell.execute_reply":"2022-02-26T14:18:33.075399Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(10,11))\nplt.title(\"TOP 50 most profitable products\", size=40, fontweight=\"bold\")\nno=50\ng = sns.barplot(y=\"prod_name\", x=\"earning(%)\", data=top_100_price_details.iloc[:no].groupby(\"prod_name\")[\"earning\"].sum() \\\n            .transform(lambda x: (x / x.sum() * 100)).rename('earning(%)').reset_index().sort_values(by=\"earning(%)\", ascending=False), \\\n            palette=\"mako\", ci=False)\nfor container in g.containers:\n    g.bar_label(container, padding = 5, fmt='%.1f', fontsize=15)\nplt.xlabel(\"Earnings (%)\", size=25, fontweight=\"bold\")\nplt.ylabel(\"\")\nplt.grid(axis=\"x\",color = 'grey', linestyle = '--', linewidth = 1.5)\nplt.show()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-02-26T14:18:33.077592Z","iopub.execute_input":"2022-02-26T14:18:33.078118Z","iopub.status.idle":"2022-02-26T14:18:33.990595Z","shell.execute_reply.started":"2022-02-26T14:18:33.078066Z","shell.execute_reply":"2022-02-26T14:18:33.989610Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, ax = plt.subplots(2,2, figsize=(13,9))\nplt.suptitle(\"TOP 100 most profitable products characteristics\", fontweight=\"bold\", fontsize=30)\n\nno=100\n\ng = sns.barplot(y=\"product_type_name\", x=\"earning(%)\", data=top_100_price_details.iloc[:no].groupby(\"product_type_name\")[\"earning\"].sum() \\\n            .transform(lambda x: (x / x.sum() * 100)).rename('earning(%)').reset_index().sort_values(by=\"earning(%)\", ascending=False), \\\n            ax=ax[0,0],palette=\"Blues_r\", ci=False)\nfor container in g.containers:\n    g.bar_label(container, padding = 5, fmt='%.1f', fontsize=14, color=\"black\")\nax[0,0].set_ylabel(\"\")\nax[0,0].set_xlabel(\"Earnings (%)\", size=20,fontweight=\"bold\")\nax[0,0].set_title(\"Product Type\", size=25,fontweight=\"bold\")\nax[0,0].grid(axis=\"x\",color = 'grey', linestyle = '--', linewidth = 1.5)\n\n\ng = sns.barplot(y=\"index_name\", x=\"earning(%)\", data=top_100_price_details.iloc[:no].groupby(\"index_name\")[\"earning\"].sum() \\\n            .transform(lambda x: (x / x.sum() * 100)).rename('earning(%)').reset_index().sort_values(by=\"earning(%)\", ascending=False), \\\n            ax=ax[0,1],palette=\"viridis\", ci=False)\nfor container in g.containers:\n    g.bar_label(container, fmt='%.1f', padding = 5, fontsize=18, color=\"black\")\nax[0,1].set_ylabel(\"\")\nax[0,1].set_xlabel(\"Earnings (%)\", size=20,fontweight=\"bold\")\nax[0,1].set_title(\"Index\", size=25,fontweight=\"bold\")\nax[0,1].grid(axis=\"x\",color = 'grey', linestyle = '--', linewidth = 1.5)\n\n\ng = sns.barplot(y=\"colour_group_name\", x=\"earning(%)\", data=top_100_price_details.iloc[:no].groupby(\"colour_group_name\")[\"earning\"].sum() \\\n            .transform(lambda x: (x / x.sum() * 100)).rename('earning(%)').reset_index().sort_values(by=\"earning(%)\", ascending=False), \\\n            ax=ax[1,0],palette=\"mako\", ci=False)\nfor container in g.containers:\n    g.bar_label(container, padding = 5, fmt='%.1f', fontsize=18, color=\"black\")\nax[1,0].set_ylabel(\"\")\nax[1,0].set_xlabel(\"Earnings (%)\", size=20,fontweight=\"bold\")\nax[1,0].set_title(\"Colour Group\", size=25,fontweight=\"bold\")\nax[1,0].grid(axis=\"x\",color = 'grey', linestyle = '--', linewidth = 1.5)\n\ng = sns.barplot(y=\"product_group_name\", x=\"earning(%)\", data=top_100_price_details.iloc[:no].groupby(\"product_group_name\")[\"earning\"].sum() \\\n            .transform(lambda x: (x / x.sum() * 100)).rename('earning(%)').reset_index().sort_values(by=\"earning(%)\", ascending=False), \\\n            ax=ax[1,1],palette=\"Reds_r\", ci=False)\nfor container in g.containers:\n    g.bar_label(container, fmt='%.1f', padding=5, fontsize=18, color=\"black\")\nax[1,1].set_ylabel(\"\")\nax[1,1].set_xlabel(\"Earnings (%)\", size=20,fontweight=\"bold\")\nax[1,1].set_title(\"Product Group\", size=25,fontweight=\"bold\")\nax[1,1].grid(axis=\"x\",color = 'grey', linestyle = '--', linewidth = 1.5)\nfig.tight_layout()\n\nplt.show() ","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-02-26T14:18:33.992185Z","iopub.execute_input":"2022-02-26T14:18:33.993075Z","iopub.status.idle":"2022-02-26T14:18:35.626490Z","shell.execute_reply.started":"2022-02-26T14:18:33.993031Z","shell.execute_reply":"2022-02-26T14:18:35.625784Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Insights:\n- Over 60% of the TOP 100 products in terms of earnings are generated by selling trousers\n- Around 50% of these products are divided (a H&M teenage collection)\n- 37% of the products are from the Ladieswear line\n- 55% of the products are black\n- 66.2% of the products are related to lower body\n\n**NOTE: It is also important to notice that the TOP 100 most profitable products list do not exactly match the TOP 100 most sold products one, since lots of products that sells a lot in quantity are cheap, and so generate less earnings.**","metadata":{}},{"cell_type":"markdown","source":"# Q4 - Which are articles that generated lower earnings for the company? ","metadata":{}},{"cell_type":"markdown","source":"After checking the most profitable products, it can be interesting to see which are the WORST 100 products in terms of earnings.","metadata":{}},{"cell_type":"code","source":"worst_100_prices=df_prices.iloc[-100:]","metadata":{"execution":{"iopub.status.busy":"2022-02-26T14:18:35.627674Z","iopub.execute_input":"2022-02-26T14:18:35.628517Z","iopub.status.idle":"2022-02-26T14:18:35.632427Z","shell.execute_reply.started":"2022-02-26T14:18:35.628467Z","shell.execute_reply":"2022-02-26T14:18:35.631829Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"worst_100_price_details = sqldf(\"\"\"SELECT *\n        FROM worst_100_prices t\n        INNER JOIN df_a a\n        on t.article_id = a.article_id\"\"\")","metadata":{"execution":{"iopub.status.busy":"2022-02-26T14:18:35.633524Z","iopub.execute_input":"2022-02-26T14:18:35.634263Z","iopub.status.idle":"2022-02-26T14:18:37.849388Z","shell.execute_reply.started":"2022-02-26T14:18:35.634224Z","shell.execute_reply":"2022-02-26T14:18:37.848620Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"worst_100_price_details.head()","metadata":{"execution":{"iopub.status.busy":"2022-02-26T14:18:37.850669Z","iopub.execute_input":"2022-02-26T14:18:37.851070Z","iopub.status.idle":"2022-02-26T14:18:37.865770Z","shell.execute_reply.started":"2022-02-26T14:18:37.851033Z","shell.execute_reply":"2022-02-26T14:18:37.864458Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, ax = plt.subplots(2,1, figsize=(25,15))\nplt.suptitle(\"FLOP 100 Worst profitable products characteristics (1)\", fontsize=40 ,fontweight=\"bold\")\n\nno=100\n\ng = sns.barplot(x=\"product_type_name\", y=\"earning(%)\", data=worst_100_price_details.iloc[:no].groupby(\"product_type_name\")[\"earning\"].sum() \\\n            .transform(lambda x: (x / x.sum() * 100)).rename('earning(%)').reset_index().sort_values(by=\"earning(%)\", ascending=False), \\\n            ax=ax[0],palette=\"mako\", ci=False)\nfor container in g.containers:\n    g.bar_label(container, fmt='%.1f', fontsize=18)\nax[0].grid(axis=\"y\",color = 'grey', linestyle = '--', linewidth = 1.5)\nax[0].set_xlabel(\"\")\nax[0].set_ylabel(\"Earnings (%)\", size=20,fontweight=\"bold\")\nax[0].set_xticklabels(g.get_xticklabels(), rotation=80)\nax[0].set_title(\"Product Type\", size=35,fontweight=\"bold\")\n\ng = sns.barplot(x=\"colour_group_name\", y=\"earning(%)\", data=worst_100_price_details.iloc[:no].groupby(\"colour_group_name\")[\"earning\"].sum() \\\n            .transform(lambda x: (x / x.sum() * 100)).rename('earning(%)').reset_index().sort_values(by=\"earning(%)\", ascending=False), \\\n            ax=ax[1],palette=\"mako\", ci=False)\nfor container in g.containers:\n    g.bar_label(container, fmt='%.1f', fontsize=18)\nax[1].set_ylabel(\"Earnings (%)\", size=20,fontweight=\"bold\")\nax[1].set_xlabel(\"\")\nax[1].set_xticklabels(g.get_xticklabels(), rotation=80)\nax[1].set_title(\"Colour Group\", size=35,fontweight=\"bold\")\nax[1].grid(axis=\"y\",color = 'grey', linestyle = '--', linewidth = 1.5)\n\n\nfig.tight_layout()\n\nplt.show() ","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-02-26T14:18:37.867320Z","iopub.execute_input":"2022-02-26T14:18:37.867581Z","iopub.status.idle":"2022-02-26T14:18:39.937893Z","shell.execute_reply.started":"2022-02-26T14:18:37.867550Z","shell.execute_reply":"2022-02-26T14:18:39.935914Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Insights: \n- 17.4% of them are t shirts\n- 12.5% are socks\n- There are quite a lot of accessories like hair bands, clips etc..","metadata":{}},{"cell_type":"code","source":"fig, ax = plt.subplots(2,1, figsize=(16,9))\nplt.suptitle(\"FLOP 100 Worst profitable products characteristics (2)\", fontsize=33 ,fontweight=\"bold\")\n\nno=100\n\ng = sns.barplot(y=\"index_name\", x=\"earning(%)\", data=worst_100_price_details.iloc[:no].groupby(\"index_name\")[\"earning\"].sum() \\\n            .transform(lambda x: (x / x.sum() * 100)).rename('earning(%)').reset_index().sort_values(by=\"earning(%)\", ascending=False), \\\n            ax=ax[0],palette=\"mako\", ci=False)\nfor container in g.containers:\n    g.bar_label(container, fmt='%.1f', fontsize=18)\nax[0].set_ylabel(\"\")\nax[0].set_xlabel(\"Earnings (%)\", size=20,fontweight=\"bold\")\nax[0].set_title(\"Index\",size=25,fontweight=\"bold\")\nax[0].grid(axis=\"x\",color = 'grey', linestyle = '--', linewidth = 1.2)\n             \ng = sns.barplot(y=\"product_group_name\", x=\"earning(%)\", data=worst_100_price_details.iloc[:no].groupby(\"product_group_name\")[\"earning\"].sum() \\\n            .transform(lambda x: (x / x.sum() * 100)).rename('earning(%)').reset_index().sort_values(by=\"earning(%)\", ascending=False), \\\n            ax=ax[1],palette=\"mako\", ci=False)\nfor container in g.containers:\n    g.bar_label(container, fmt='%.1f', fontsize=18)\nax[1].set_ylabel(\"\")\nax[1].set_xlabel(\"Earnings (%)\", size=20,fontweight=\"bold\")\nax[1].set_title(\"Product Group\", size=25,fontweight=\"bold\")\nax[1].grid(axis=\"x\",color = 'grey', linestyle = '--', linewidth = 1.5)\n             \nplt.tight_layout()\n             \nplt.show()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-02-26T14:18:39.940478Z","iopub.execute_input":"2022-02-26T14:18:39.940921Z","iopub.status.idle":"2022-02-26T14:18:40.825780Z","shell.execute_reply.started":"2022-02-26T14:18:39.940843Z","shell.execute_reply":"2022-02-26T14:18:40.824790Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Insights:\n- 38.7% of these only sonce once products are accessories\n- Around 35% of these products are for children of babies","metadata":{}},{"cell_type":"markdown","source":"# Customer Analayis","metadata":{}},{"cell_type":"markdown","source":"In the following, we will start an analysis on the customers to find interesting insights and understand which customers are responsible for msot purchases.","metadata":{}},{"cell_type":"code","source":"df_t.head()","metadata":{"execution":{"iopub.status.busy":"2022-02-26T14:18:40.827302Z","iopub.execute_input":"2022-02-26T14:18:40.827572Z","iopub.status.idle":"2022-02-26T14:18:40.839260Z","shell.execute_reply.started":"2022-02-26T14:18:40.827538Z","shell.execute_reply":"2022-02-26T14:18:40.837980Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"In order to perform the analysis, we first decide to  create a new dataframe that will include, for each row, an unique customer_id, the total purchased quantity by that customer and the ernings generated by the company by the purchases of that customer.","metadata":{}},{"cell_type":"markdown","source":"First, we crate a dataframe which will include the unique customer ids and the earnings generated by theirs purchases.","metadata":{}},{"cell_type":"code","source":"df_cust_prices = df_t[[\"customer_id\", \"price\"]].groupby(\"customer_id\").sum()","metadata":{"execution":{"iopub.status.busy":"2022-02-26T14:18:40.840783Z","iopub.execute_input":"2022-02-26T14:18:40.841857Z","iopub.status.idle":"2022-02-26T14:18:55.350785Z","shell.execute_reply.started":"2022-02-26T14:18:40.841738Z","shell.execute_reply":"2022-02-26T14:18:55.349843Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_cust_prices.head()","metadata":{"execution":{"iopub.status.busy":"2022-02-26T14:18:55.352177Z","iopub.execute_input":"2022-02-26T14:18:55.353054Z","iopub.status.idle":"2022-02-26T14:18:55.362721Z","shell.execute_reply.started":"2022-02-26T14:18:55.353009Z","shell.execute_reply":"2022-02-26T14:18:55.361422Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Second, we create a dataframe that will include the unique customer ids and their total purchased quantity of products.","metadata":{}},{"cell_type":"code","source":"df_cust_qty = df_t[[\"customer_id\", \"article_id\"]].groupby(\"customer_id\").count()","metadata":{"execution":{"iopub.status.busy":"2022-02-26T14:18:55.364118Z","iopub.execute_input":"2022-02-26T14:18:55.364480Z","iopub.status.idle":"2022-02-26T14:19:09.407653Z","shell.execute_reply.started":"2022-02-26T14:18:55.364446Z","shell.execute_reply":"2022-02-26T14:19:09.406795Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_cust_qty.head()","metadata":{"execution":{"iopub.status.busy":"2022-02-26T14:19:09.408835Z","iopub.execute_input":"2022-02-26T14:19:09.409072Z","iopub.status.idle":"2022-02-26T14:19:09.419049Z","shell.execute_reply.started":"2022-02-26T14:19:09.409045Z","shell.execute_reply":"2022-02-26T14:19:09.418137Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Then, we join these two dataframe to a new one \"cust_qty_price\", which will include the unique customer ids, their purchased quantity and the earnings generated by the company by their purchases.","metadata":{}},{"cell_type":"code","source":"cust_qty_price = pd.merge(df_cust_prices, df_cust_qty, on='customer_id', how='inner')","metadata":{"execution":{"iopub.status.busy":"2022-02-26T14:19:09.420500Z","iopub.execute_input":"2022-02-26T14:19:09.420803Z","iopub.status.idle":"2022-02-26T14:19:11.056732Z","shell.execute_reply.started":"2022-02-26T14:19:09.420771Z","shell.execute_reply":"2022-02-26T14:19:11.056029Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cust_qty_price.head()","metadata":{"execution":{"iopub.status.busy":"2022-02-26T14:19:11.057834Z","iopub.execute_input":"2022-02-26T14:19:11.058531Z","iopub.status.idle":"2022-02-26T14:19:11.067809Z","shell.execute_reply.started":"2022-02-26T14:19:11.058497Z","shell.execute_reply":"2022-02-26T14:19:11.067083Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Finally we can join this new dataframe to the Customer dataframe df_c, so that we can add some informations about the customer on the newly defined cust_qty_price dataframe.","metadata":{}},{"cell_type":"code","source":"df_c.head()","metadata":{"execution":{"iopub.status.busy":"2022-02-26T14:19:11.068887Z","iopub.execute_input":"2022-02-26T14:19:11.069212Z","iopub.status.idle":"2022-02-26T14:19:11.093540Z","shell.execute_reply.started":"2022-02-26T14:19:11.069183Z","shell.execute_reply":"2022-02-26T14:19:11.092926Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cust_details = pd.merge(cust_qty_price, df_c.drop(\"postal_code\", axis=1), on='customer_id', how='inner')","metadata":{"execution":{"iopub.status.busy":"2022-02-26T14:19:11.095034Z","iopub.execute_input":"2022-02-26T14:19:11.095530Z","iopub.status.idle":"2022-02-26T14:19:13.321978Z","shell.execute_reply.started":"2022-02-26T14:19:11.095496Z","shell.execute_reply":"2022-02-26T14:19:13.321035Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cust_details.head()","metadata":{"execution":{"iopub.status.busy":"2022-02-26T14:19:13.323269Z","iopub.execute_input":"2022-02-26T14:19:13.323601Z","iopub.status.idle":"2022-02-26T14:19:13.339905Z","shell.execute_reply.started":"2022-02-26T14:19:13.323558Z","shell.execute_reply":"2022-02-26T14:19:13.339031Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f\"In total there are {len(cust_details)} different customers\")","metadata":{"execution":{"iopub.status.busy":"2022-02-26T14:19:13.341408Z","iopub.execute_input":"2022-02-26T14:19:13.341931Z","iopub.status.idle":"2022-02-26T14:19:13.355564Z","shell.execute_reply.started":"2022-02-26T14:19:13.341865Z","shell.execute_reply":"2022-02-26T14:19:13.354447Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Purchased Quantity by Customer Analysis","metadata":{"execution":{"iopub.status.busy":"2022-02-24T08:46:46.6228Z","iopub.execute_input":"2022-02-24T08:46:46.623519Z","iopub.status.idle":"2022-02-24T08:46:46.631323Z","shell.execute_reply.started":"2022-02-24T08:46:46.623472Z","shell.execute_reply":"2022-02-24T08:46:46.629881Z"}}},{"cell_type":"markdown","source":"Now we will analyze the purchased quantity by the customers.","metadata":{}},{"cell_type":"code","source":"cust_details.article_id.describe()","metadata":{"execution":{"iopub.status.busy":"2022-02-26T14:19:13.356774Z","iopub.execute_input":"2022-02-26T14:19:13.357398Z","iopub.status.idle":"2022-02-26T14:19:13.418107Z","shell.execute_reply.started":"2022-02-26T14:19:13.357352Z","shell.execute_reply":"2022-02-26T14:19:13.417248Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"By calling the \"describe\" method on the \"article_id\" column, we can observe that:\n- The minimum purchased quantity by a single customer is 1\n- 25% of customers Purchased 3 or less items\n- 50% of customers Purchased 9 or less items\n- 75% of customers Purchased 27 or less items\n- The maximum purchased quantity by a single customer is 1895 products","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(10,4))\nplt.title(\"Distribution of purchased quantity by customer\", fontweight=\"bold\", size=20)\nsns.kdeplot(cust_details[\"article_id\"])\nplt.xlabel(\"purchased quantity\",fontweight=\"bold\", size=20)\nplt.ylabel(\"Count\",fontweight=\"bold\", size=20)\nplt.show()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-02-26T14:19:13.419475Z","iopub.execute_input":"2022-02-26T14:19:13.419953Z","iopub.status.idle":"2022-02-26T14:19:18.221390Z","shell.execute_reply.started":"2022-02-26T14:19:13.419919Z","shell.execute_reply":"2022-02-26T14:19:18.220545Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Indeed, the distribution of this variable is highly skewed.","metadata":{}},{"cell_type":"markdown","source":"Next, we will analyze the age and other provided features of the customer to better find insights on the customers and their purchase behaviour.","metadata":{}},{"cell_type":"markdown","source":"# Purchase Behaviors according to Age","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(10,5))\nplt.title(\"Customers age distribution\", fontweight=\"bold\", size=30)\nplt.hist(cust_details[\"age\"], bins=70, edgecolor=\"black\", color=\"#1ABC9C\")\nplt.xlabel(\"Age\",fontweight=\"bold\", size=20)\nplt.ylabel(\"Count\",fontweight=\"bold\", size=20)\nplt.show()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-02-26T14:19:18.222727Z","iopub.execute_input":"2022-02-26T14:19:18.223538Z","iopub.status.idle":"2022-02-26T14:19:18.681987Z","shell.execute_reply.started":"2022-02-26T14:19:18.223490Z","shell.execute_reply":"2022-02-26T14:19:18.681163Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**The distribution of the age feature is bivariate. In order to create more effective plots, we will create a categorical column for age which divides the ages in age groups.**","metadata":{}},{"cell_type":"markdown","source":"# Q5 - Which age group purchase more articles?","metadata":{}},{"cell_type":"code","source":"cust_details['age_groups'] = pd.cut(cust_details['age'], bins=[16, 20, 30, 40,50, 60, 70, float('Inf')], labels=['16-20', '20-30','30-40','40-50','50-60','60-70' , '70+'])","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-02-26T14:19:18.683398Z","iopub.execute_input":"2022-02-26T14:19:18.683707Z","iopub.status.idle":"2022-02-26T14:19:18.737590Z","shell.execute_reply.started":"2022-02-26T14:19:18.683667Z","shell.execute_reply":"2022-02-26T14:19:18.736773Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(8,5))\nplt.title(\"Purchased quantity by age group\\n\", fontweight=\"bold\", size=28)\ng = sns.barplot(x=\"age_groups\", y=\"Purchased Quantity(%)\", data=cust_details.groupby(\"age_groups\")[\"article_id\"].sum() \\\n            .transform(lambda x: (x / x.sum() * 100)).rename('Purchased Quantity(%)').reset_index(), palette=\"icefire\", edgecolor=\"black\")\nplt.xlabel(\"Age Group\",fontweight=\"bold\", size=22)\nplt.ylabel(\"Purchased Quantity (%)\",fontweight=\"bold\", size=19)\nfor container in g.containers:\n    g.bar_label(container, padding = 5, fmt='%.1f', fontsize=18, color=\"black\")\nplt.grid(axis=\"y\",color = 'grey', linestyle = '--', linewidth = 1.5)\nplt.show()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-02-26T14:19:18.739097Z","iopub.execute_input":"2022-02-26T14:19:18.739895Z","iopub.status.idle":"2022-02-26T14:19:19.118839Z","shell.execute_reply.started":"2022-02-26T14:19:18.739828Z","shell.execute_reply":"2022-02-26T14:19:19.117965Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Insights:\n- Customers in the range 20-30 are responsible for more than 42% of the total purchased products.\n- Customers in the range 16-20. 60-70 and 70+ are responsible for the 8% of the total purchased products\n- Customers in the range 30-40, 40-50 and 50-60 are responsible for 16% of purchased quantity each.","metadata":{}},{"cell_type":"markdown","source":"After analyzing the purchases quantity, it could be interesting to analyze the earnings provided to the company by each customer.","metadata":{"execution":{"iopub.status.busy":"2022-02-24T09:09:34.101437Z","iopub.execute_input":"2022-02-24T09:09:34.101783Z","iopub.status.idle":"2022-02-24T09:09:34.108475Z","shell.execute_reply.started":"2022-02-24T09:09:34.101748Z","shell.execute_reply":"2022-02-24T09:09:34.107457Z"}}},{"cell_type":"markdown","source":"# Q6 - Which age group generates more earnings for the company?","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(8,5))\nplt.title(\"Company Earnings by age group\\n\", fontweight=\"bold\", size=28)\ng = sns.barplot(x=\"age_groups\", y=\"earning(%)\", data=cust_details.groupby(\"age_groups\")[\"price\"].sum() \\\n            .transform(lambda x: (x / x.sum() * 100)).rename('earning(%)').reset_index(), palette=\"icefire\",edgecolor=\"black\")\nplt.xlabel(\"Age Group\",fontweight=\"bold\", size=22)\nplt.ylabel(\"Earnings (%)\",fontweight=\"bold\", size=25)\nfor container in g.containers:\n    g.bar_label(container, padding = 5, fmt='%.1f', fontsize=18, color=\"black\")\nplt.grid(axis=\"y\",color = 'grey', linestyle = '--', linewidth = 1.5)\nplt.show()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-02-26T14:19:19.120402Z","iopub.execute_input":"2022-02-26T14:19:19.120917Z","iopub.status.idle":"2022-02-26T14:19:19.486290Z","shell.execute_reply.started":"2022-02-26T14:19:19.120854Z","shell.execute_reply":"2022-02-26T14:19:19.485454Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"\n**Indeed a very similar situation to the purchases quantity can be found in the earnings analysis, since customers who buys more, on average leads to higher earnings for the company. <br>\nThe age group 20-30 is by far responsible for the highest earnings for the company (41.9% of total earnings).**","metadata":{}},{"cell_type":"markdown","source":"# Q7 - Do active customers on the fashion news purchase more articles?","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(9,5))\nplt.title(\"Purchased quantity by Fashion News Frequency\\n\", fontweight=\"bold\", size=20)\ng = sns.barplot(x=\"fashion_news_frequency\", y=\"Purchased Quantity(%)\", data=cust_details.groupby(\"fashion_news_frequency\")[\"article_id\"].sum() \\\n            .transform(lambda x: (x / x.sum() * 100)).rename('Purchased Quantity(%)').reset_index(), palette=\"Spectral\", edgecolor=\"black\")\nplt.xlabel(\"Fashion News Frequency\",fontweight=\"bold\", size=22)\nplt.ylabel(\"Purchased Quantity (%)\",fontweight=\"bold\", size=25)\nfor container in g.containers:\n    g.bar_label(container, padding = 5, fmt='%.3f', fontsize=18, color=\"black\")\nplt.grid(axis=\"y\",color = 'grey', linestyle = '--', linewidth = 1.5)\nplt.show()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-02-26T14:19:19.487795Z","iopub.execute_input":"2022-02-26T14:19:19.488293Z","iopub.status.idle":"2022-02-26T14:19:19.969569Z","shell.execute_reply.started":"2022-02-26T14:19:19.488249Z","shell.execute_reply":"2022-02-26T14:19:19.968622Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Active customers on the fashion news are responsible for 43% of the total purchases, while the remaining 57% of purchased quantity comes from customer not registed in the fashion news.** <br>\nThe other 2 categories \"Monthly\" and \"None\" can be ignored and won't be considered for the further analysis.","metadata":{}},{"cell_type":"markdown","source":"So then it could be interesting to check the fashion news frequency by age group, to find more useful insights,","metadata":{}},{"cell_type":"code","source":"x, y = 'age_groups', 'fashion_news_frequency'\ndf_age_news = cust_details.groupby(x)[y].value_counts(normalize=True)\ndf_age_news = df_age_news.mul(100)\ndf_age_news = df_age_news.rename('percent(%)').reset_index()\ndf_age_news = df_age_news[df_age_news[\"fashion_news_frequency\"].isin([\"Regularly\",\"NONE\"])]","metadata":{"execution":{"iopub.status.busy":"2022-02-26T14:19:19.971064Z","iopub.execute_input":"2022-02-26T14:19:19.971412Z","iopub.status.idle":"2022-02-26T14:19:20.345379Z","shell.execute_reply.started":"2022-02-26T14:19:19.971368Z","shell.execute_reply":"2022-02-26T14:19:20.344469Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"palette1 = {\"Regularly\":'#46C646', \"NONE\":'#FF0000'}\n\nplt.figure(figsize=(13,6))\nplt.title(\"Fashion News Frequency by age group\\n\",fontweight=\"bold\", size=33)\ng=sns.barplot(x=\"age_groups\", y=\"percent(%)\",data=df_age_news, hue=\"fashion_news_frequency\", palette=palette1)\nplt.xlabel(\"Age group\",fontweight=\"bold\", size=22)\nplt.ylabel(\"Percentage (%)\",fontweight=\"bold\", size=25)\nfor container in g.containers:\n    g.bar_label(container, padding = 5, fmt='%.1f', fontsize=16, color=\"black\")\nplt.grid(axis=\"y\",color = 'grey', linestyle = '--', linewidth = 1.5)\nplt.legend(title='News\\nFrequency',bbox_to_anchor=(1.0, 1.0), ncol=1, fancybox=True, shadow=True, fontsize=17,title_fontsize=22)\nplt.show()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-02-26T14:19:20.346658Z","iopub.execute_input":"2022-02-26T14:19:20.346963Z","iopub.status.idle":"2022-02-26T14:19:20.853405Z","shell.execute_reply.started":"2022-02-26T14:19:20.346931Z","shell.execute_reply":"2022-02-26T14:19:20.852506Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We can see that **customers in the range 20-30 and 30-40 have the lowest percentage of fashion news frequency, while being the groups which buy the most**.<br>\nMoreover, **the frequency of customer that regulary check fashion news starts increasing from the range 40-50, with a peak value of 43.7% of regular/active users for customers in the range 70+ years old**. This means that **checking fashion news seems to be more effective for older customers, who still represent a small percentage of total sold products, while younger customers do not need to check the news to buy new products**. <br>\n**It could be effective for the company to invite younger customers (range 20-40) to check the news more frequently in order to increase the sold items.**","metadata":{}},{"cell_type":"markdown","source":"# Q8 - Does the club member status influence the purchased quantity?","metadata":{}},{"cell_type":"code","source":"cust_details[\"club_member_status\"].value_counts(normalize=True)","metadata":{"execution":{"iopub.status.busy":"2022-02-26T14:19:20.854690Z","iopub.execute_input":"2022-02-26T14:19:20.855226Z","iopub.status.idle":"2022-02-26T14:19:21.076477Z","shell.execute_reply.started":"2022-02-26T14:19:20.855167Z","shell.execute_reply":"2022-02-26T14:19:21.075439Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We can see that:\n- More than 93% of the customers belong to the ACTIVE category\n- 6.8% of the customers belong to the PRE-CREATE cateory\n- 0.3% of the customers belong to the LEFT CLUB category","metadata":{}},{"cell_type":"markdown","source":"**This shows a very high imbalance among the classes: if we consider the sum of purchased products per each category, this will likely show that the most part of Purchased products belongs to the ACTIVE members.**","metadata":{}},{"cell_type":"code","source":"cust_details.groupby(\"club_member_status\")[\"article_id\"].sum()","metadata":{"execution":{"iopub.status.busy":"2022-02-26T14:19:21.077748Z","iopub.execute_input":"2022-02-26T14:19:21.078002Z","iopub.status.idle":"2022-02-26T14:19:21.282776Z","shell.execute_reply.started":"2022-02-26T14:19:21.077972Z","shell.execute_reply":"2022-02-26T14:19:21.281661Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Indeed, more customers in a group leads to higher purchases. For this reason, it is more wise to consider a mean Purchased quantity instead of a sum:**","metadata":{}},{"cell_type":"code","source":"print(\"The average quantity of purchased products by the customers is {:.0f} products \".format(cust_details[\"article_id\"].mean()))","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-02-26T14:19:21.284227Z","iopub.execute_input":"2022-02-26T14:19:21.284511Z","iopub.status.idle":"2022-02-26T14:19:21.292236Z","shell.execute_reply.started":"2022-02-26T14:19:21.284471Z","shell.execute_reply":"2022-02-26T14:19:21.290955Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"The average quantity of purchased products by the ACTIVE customers is {:.0f} products \".format(cust_details.groupby(\"club_member_status\")[\"article_id\"].mean()[\"ACTIVE\"]))\nprint(\"The average quantity of purchased products by the LEFT-CLUB customers is {:.0f} products \".format(cust_details.groupby(\"club_member_status\")[\"article_id\"].mean()[\"LEFT CLUB\"]))\nprint(\"The average quantity of purchased products by the PRE-CREATE customers is {:.0f} products \".format(cust_details.groupby(\"club_member_status\")[\"article_id\"].mean()[\"PRE-CREATE\"]))","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-02-26T14:19:21.293549Z","iopub.execute_input":"2022-02-26T14:19:21.293814Z","iopub.status.idle":"2022-02-26T14:19:21.887827Z","shell.execute_reply.started":"2022-02-26T14:19:21.293773Z","shell.execute_reply":"2022-02-26T14:19:21.886842Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"By considering the mean, we can see a very different situation, which will be shown as percentages in the following plot:","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(9,5))\nplt.title(\"Average Purchased Quantity by Club Member Status\\n\", fontweight=\"bold\", size=22)\ng = sns.barplot(x=\"club_member_status\", y=\"article_id\", data=cust_details.groupby(\"club_member_status\")[\"article_id\"].mean().astype(int).reset_index(), palette=\"viridis\", edgecolor=\"black\")\nplt.axhline(y = cust_details[\"article_id\"].mean(), color = 'r', linestyle = '--')\nplt.text(0.76, 23.7, 'Mean Purchased Quantity: {:.0f}'.format(cust_details[\"article_id\"].mean()), size=16, color=\"red\",fontweight=\"bold\")\nplt.xlabel(\"Club Member Status\",fontweight=\"bold\", size=20)\nplt.ylabel(\"Average Purchased Quantity\",fontweight=\"bold\", size=16)\nfor container in g.containers:\n    g.bar_label(container, padding = 5, fmt='%.0f', fontsize=23, color=\"black\")\nplt.grid(axis=\"y\",color = 'grey', linestyle = '--', linewidth = 1.5)\nplt.show()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-02-26T14:19:21.889094Z","iopub.execute_input":"2022-02-26T14:19:21.889352Z","iopub.status.idle":"2022-02-26T14:19:22.376078Z","shell.execute_reply.started":"2022-02-26T14:19:21.889323Z","shell.execute_reply":"2022-02-26T14:19:22.375353Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**This plots shows that the average purchased quantity differs a lot among the categories**. <br>\nIn particular, **customers belonging to the ACTIVE clubs, purchase more products than other categories, while those in the \"pre-create\" category purchaes on average less than a third of third of active customers**.","metadata":{}},{"cell_type":"markdown","source":"Finally, since the distribution of the purchased quantity is heavily right skewed, it could be interesting to check out also the median purhcased quantity.","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(9,5))\nplt.title(\"Median Purchased Quantity by Club Member Status\\n\", fontweight=\"bold\", size=22)\ng = sns.barplot(x=\"club_member_status\", y=\"article_id\", data=cust_details.groupby(\"club_member_status\")[\"article_id\"].median().reset_index(), palette=\"viridis\", edgecolor=\"black\")\nplt.axhline(y = cust_details[\"article_id\"].median(), color = 'r', linestyle = '--')\nplt.text(0.76, 9.3, 'Median Purchased Quantity: {:.2f}'.format(cust_details[\"article_id\"].median()), size=16, color=\"red\",fontweight=\"bold\")\nplt.xlabel(\"Club Member Status\",fontweight=\"bold\", size=20)\nplt.ylabel(\"Median Purchaed Quantity\",fontweight=\"bold\", size=16)\nfor container in g.containers:\n    g.bar_label(container, padding = 5, fmt='%.0f', fontsize=23, color=\"black\")\nplt.grid(axis=\"y\",color = 'grey', linestyle = '--', linewidth = 1.5)\nplt.show()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-02-26T14:19:22.377254Z","iopub.execute_input":"2022-02-26T14:19:22.377606Z","iopub.status.idle":"2022-02-26T14:19:22.911743Z","shell.execute_reply.started":"2022-02-26T14:19:22.377575Z","shell.execute_reply":"2022-02-26T14:19:22.910771Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Indeed, even if the Median is quite different for the Mean due to high skeweness of the data, a very similar situation situation to the mean purchases quantity can be observed, where ACTIVE customers buys more product on average.","metadata":{}},{"cell_type":"markdown","source":"**This Notebook is still a W.I.P., I will update it with predictions or more data analysis if I have new ideas !!**","metadata":{}},{"cell_type":"markdown","source":"**Thank your for checking out my notebook! Let me know if you have comments or if you want me to check out your work! :)**","metadata":{}}]}