#!/usr/bin/env python
# coding: utf-8

# # Ejercicio Transacciones. Parte 3 - Explotación del dato.

# In[1]:


import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from datetime import datetime

import warnings
warnings.filterwarnings('ignore')

pd.options.display.float_format = '{:.2f}'.format #Desactivar notación científica en pandas:
np.set_printoptions(suppress=True) #Desactivar notación científica en numpy:
pd.set_option('display.max_columns', None) #comando para mostrar todas las columnas


# #### Uno de los problemas de trabajar con CSVs es que no se guarda el tipo de dato que contiene, por lo que al cargar el CSV deberemos comprobar que los tipos sean los correctos.

# In[2]:


sep = ";"
decimal = ","
index=False
encoding="UTF-8"


# In[3]:


df = pd.read_csv('./data/transacciones2.csv', sep=sep, decimal=decimal, encoding=encoding)


# In[4]:


df.info()


# In[5]:


# Modificamos el campo Fecha para que sea una fecha y el código postal a string
df['Fecha'] = pd.to_datetime(df['Fecha'].astype('string'))
df['Código Postal'] = df['Código Postal'].astype('string')


# Enriquecemos el set de datos con nueva información.

# In[6]:


df['dia'] = df.Fecha.dt.day
df['mes'] = df.Fecha.dt.month
df['anio'] = df.Fecha.dt.year
df['diaSemana'] = df.Fecha.dt.weekday  # el 0 corresponde al lunes


# In[7]:


df


# In[8]:


#df['diaSemana'][df.Fecha == '2015-01-05']


# In[9]:


# Enriquecemos más...
filtro = ((df['diaSemana'] == 4) | (df['diaSemana'] == 5) | (df['diaSemana'] == 6))

df['Fin de semana'] = 0  #  Si es 1 será fin de semana


# In[10]:


df['Fin de semana'] [filtro] = 1
#df['Fin de semana'][((df['diaSemana'] == 4) | (df['diaSemana'] == 5) | (df['diaSemana'] == 6))] = 1
df


# In[11]:


# Seguimos enriqueciendo...
filtro = ((df.mes == 7) | (df.mes==8))
df['Verano'] = 0
df['Verano'][filtro] = 1  # indica que la transacción se realizó en verano

df['primeroMes'] = 0
filtro = df.dia<=10
df['primeroMes'][filtro] = 1

df['finalMes'] = 0
filtro = df.dia>=20
df['finalMes'][filtro] = 1


# In[12]:


df


# In[13]:


#df['Fin de semana'] = df['Fin de semana'].astype('boolean')
#df['Verano'] = df['Verano'].astype('boolean')
#df['primeroMes'] = df['primeroMes'].astype('boolean')
#df['finalMes'] = df['finalMes'].astype('boolean')


# In[14]:


df.info()


# #### Hasta aquí el enriquecimiento.  Ahora unas agregaciones...

# #### ¿Qué tipo de comercios se ven más afectados en fin de semana?

# In[15]:


datosplot = df.pivot_table(
    index=['Fin de semana'],
    columns=['Tipo de Comercio'], 
    values='Importe Total', 
    aggfunc=np.sum).transpose()
datosplot.rename({0:"NFSemana",1:"FSemana"}, axis=1, inplace=True)
datosplot


# In[16]:


# Añadimos una columna de totales
totales = df.pivot_table (
    index=['Tipo de Comercio'],
    values='Importe Total', 
    aggfunc=np.sum)


# In[17]:


totales


# In[18]:


datosplot = pd.merge(datosplot, totales, left_index=True, right_index=True)
datosplot.sort_values('Importe Total', ascending=True, inplace=True)
# Añado el índice como una nueva columna
#datosplot ['Comercio'] = datosplot.index
datosplot.reset_index(inplace=True)


# In[19]:


datosplot


# In[20]:


plt.rcParams['figure.figsize'] = (20, 20)
datosplot.plot(x = 'Tipo de Comercio', y=['NFSemana','FSemana'], kind="barh")
plt.xticks(rotation=90)
plt.xticks(fontsize=15)
plt.title("Comparación ventas NFS/FS")


# #### Quizás así se ve mejor

# In[22]:


plt.rcParams['figure.figsize'] = (20, 20)
datosplot.plot(x = 'Tipo de Comercio', y=['NFSemana','FSemana'], kind="barh", stacked=True)
plt.xticks(rotation=90)
plt.xticks(fontsize=15)
plt.title("Comparación ventas NFS/FS")


# #### En ambas gráficas tenemos probablemente demasiados elementos.
# #### También podemos extraer los porcentajes de venta, en función de si la venta se ha realizado en fin de semana o no.

# In[23]:


datosplot2 = df.pivot_table(
    columns=['Fin de semana'], 
    values='Importe Total', 
    aggfunc=np.sum)
datosplot2.rename({0:"NFSemana",1:"FSemana"}, axis=1, inplace=True)
datosplot2


# In[24]:


plt.rcParams['figure.figsize'] = (7, 7)
datosplot2.plot(y=['NFSemana','FSemana'], kind="bar")
plt.xticks(rotation=0)
plt.rcParams['figure.figsize'] = (10, 10)
plt.title("Comparación ventas NFS/FS")


# #### Generamos el nuevo set de datos para ver más claro a que tipo de comercio le afectan menos los fines de semana.

# In[26]:


datosplot3 = df.pivot_table(
    columns = ['Fin de semana', 'Tipo de Comercio'],
    values = ['Importe Total'],
    aggfunc=np.sum).transpose().reset_index()

datosplot4 = df.pivot_table(
    columns = ['Tipo de Comercio'],
    values = ['Importe Total'],
    aggfunc=np.sum).transpose().reset_index()


# In[27]:


datosplot5 = pd.merge(
    datosplot3,
    datosplot4,
    how = 'left',
    on = 'Tipo de Comercio',
    sort = True)


# In[28]:


datosplot5


# In[29]:


datosplot5.rename({'Importe Total_x':'Importe Total','Importe Total_y':'Importe Total Año'}, axis=1, inplace=True)


# #### Ahora relativizamos los datos en base cuándo se produce la venta (finde o no)

# In[30]:


datosplot5 ['porc_importetotal'] = datosplot5['Importe Total'] / datosplot5 ['Importe Total Año']
datosplot5.reset_index(drop=True, inplace=True)


# In[31]:


datosplot5


# In[47]:


datosplot5.porc_importetotal


# In[32]:


# Divido los datos en 2 partes.  No es necesario, pero lo hago por claridad.
laborables = datosplot5 [datosplot5['Fin de semana'] == 0]
festivos = datosplot5 [datosplot5['Fin de semana'] == 1]


# In[49]:


# Pintamos...
plt.rcParams['figure.figsize'] = (10, 10)
plt.xticks(rotation=90)
plt.xticks(fontsize=10)
plt.bar(
    laborables['Tipo de Comercio'], 
    laborables['porc_importetotal'], 
    color = 'b', 
    width=1)

plt.bar(
    festivos['Tipo de Comercio'], 
    festivos['porc_importetotal'], 
    color = 'r', 
    width=1, 
    bottom = laborables['porc_importetotal'])


# #### En ese formato no se ve muy claramente, qué comercios se ven más afectados por los fines de semana.  Hacemos cambios...

# In[87]:


festivos = datosplot5 [datosplot5['Fin de semana'] == 1]
festivos.sort_values('porc_importetotal', ascending=True)


# In[95]:


import matplotlib.lines as lines

# Pintamos...
plt.rcParams['figure.figsize'] = (15, 15)
plt.xticks(rotation=90)
plt.xticks(fontsize=15)
plt.bar(
    festivos['Tipo de Comercio'], 
    festivos['porc_importetotal'].sort_values(ascending=True), 
    color = 'r', 
    width=1)

plt.axhline(y=0.5,linewidth=2, color='k')
plt.axhline(y=3/7,linewidth=2, color='b')
plt.show()


# In[90]:


# Vemos los 10 comercios más afectados por los fines de semana
festivos.head(10)


# #### ¿Puedes comprobar cuáles son los 5 tipos de comercio más afectados por el efecto semana laboral? (Cuáles son los que más venden)

# ####  Probamos otras opciones, como el código postal o el día de la semana (o mes), ...

# In[138]:


# Miramos cómo influye en las ventas la localización del tipo de comercio
# Me interesa crear una tabla en la que tengamos una columna con los tipos de comercio, otra con el código postal y otra con el importe total.  
# Básicamente será una tabla en formato largo
datosplot6 = pd.pivot_table(data = df, columns = ['Tipo de Comercio', 'Código Postal'], values = 'Importe Total', aggfunc=sum).transpose().reset_index()


# In[139]:


datosplot6


# In[ ]:


plt.rcParams['figure.figsize'] = (20, 20)
plt.xticks(rotation=90)
plt.xticks(fontsize=10)
sns.barplot(data=datosplot6, x='Tipo de Comercio', y='Importe Total', hue='Código Postal')


# In[147]:


# Y por día de la semana
datosplot7 = pd.pivot_table(data = df, columns = ['Tipo de Comercio', 'diaSemana'], values = 'Importe Total', aggfunc=sum).transpose().reset_index()


# In[148]:


datosplot7


# In[149]:


plt.rcParams['figure.figsize'] = (20, 20)
plt.xticks(rotation=90)
plt.xticks(fontsize=10)
sns.barplot(data=datosplot7, x='Tipo de Comercio', y='Importe Total', hue='diaSemana')


# In[150]:


# Probamos a representar por CP, las ventas de café, apuestas y parking.
# Partimos de aquí
datosplot6


# In[162]:


# Filtramos...
filtro = ((datosplot6['Tipo de Comercio'] == "es_cafe") | (datosplot6['Tipo de Comercio'] == "es_parking") | (datosplot6['Tipo de Comercio'] == "es_bet"))
datosplot8 = datosplot6 [filtro]


# In[164]:


datosplot8


# In[165]:


plt.rcParams['figure.figsize'] = (20, 20)
plt.xticks(rotation=90)
plt.xticks(fontsize=10)
sns.barplot(data=datosplot8, x='Código Postal', y='Importe Total', hue='Tipo de Comercio')


# #### ¿En qué CP se realizan más ventas? ¿y de mayor volumen?
# #### Deberemos dividir el proceso en varias partes.
# #### *Calcular la suma total de transacciones por CP
# #### *Calcular la suma total de importes por CP
# #### *Unir ambos resultados por CP
# #### *Calcular el importe medio (importe total / transacciones)
# #### *Pintar el resultado
# 
# 
