El objetivo de este trabajo es hacer un análisis de los contratos menores del Ayuntamiento de Madrid desde 2015 para hacer una comparativa por años y ver qué empresas han resultado más beneficiadas.
Datos abiertos del Ayuntamiento de Madrid: Contratos menores
In [9]:
    
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import datetime as dt
from urllib.error import HTTPError
try:
    df = pd.read_csv('http://aprendeconalf.es/python/trabajos/datos/contratos-menores-madrid.csv', sep=';')
except HTTPError:
    print('La url no existe')
else:
    # Preprocesamiento de datos
    # # Ordenar el dataframe por años
    df = df.sort_values(['AÑO'])
    print(df)
    
    
In [10]:
    
def empresa(df, nif):
    """
    Función que devuelve el nombre de la empresa con el nif dado.
    Parámetros:
        - df: Es un DataFrame con la información de la base de datos de los contratos menores.
        - nif: Es una cadena con el NIF del contratista.
    Devuelve:
        El nombre del contratista.
    """
    return df[df['NIF']==nif]['CONTRATISTA'].iloc[0]
    
In [11]:
    
def facturacion_empresa_años(df, nif, años):
    """
    Función que devuelve un diccionario con el número de contratos y el total facturado por la empresa durante una lista de años.
    Parámetros: 
        - df: Es un DataFrame con la información de la base de datos de los contratos menores.
        - nif: Es una cadena con el NIF del contratista.
        - años: Es una lista con los años. 
    Devuelve:
        Un diccionario con el número de contratos y el total facturado por la empresa con el nif dado durante los años indicados.
    """
    # Filtro de la empresa y los años
    df1 = df[(df['NIF'] == nif) & (df['AÑO'].isin(años))]
    return {'Número de contratos': df1['IMPORTE'].count(), 'Total facturado':df1['IMPORTE'].sum()}
# Ejemplo
print(facturacion_empresa_años(df, 'B28380582', [2018, 2019]))
    
    
In [12]:
    
def gasto_seccion_años(df, seccion, años):
    """
    Función que devuelve un diccionario con el número de contratos y el total gastado por una sección del ayuntamiento durante una lista de años.
    Parámetros: 
        - df: Es un DataFrame con la información de la base de datos de los contratos menores.
        - seccion: Es una cadena con la sección del ayuntamiento que ordena el gasto.
        - años: Es una lista con los años. 
    Devuelve:
        Un diccionario con el número de contratos y el total facturado por la empresa con el nif dado durante los años indicados.
    """
    # Filtro de la sección y los años
    df1 = df[(df['SECCION'] == seccion) & (df['AÑO'].isin(años))]
    return {'Número de contratos': df1['IMPORTE'].count(), 'Total gastado':df1['IMPORTE'].sum()}
# Ejemplo
print(gasto_seccion_años(df, 'EMPRESA MUNICIPAL DE TRANSPORTES S.A.', [2018, 2019]))
    
    
In [13]:
    
def facturacion_empresa_seccion_años(df, nif, seccion, años):
    """
    Función que devuelve un diccionario con el número de contratos y el total facturado por la empresa a una seccion durante una lista de años.
    Parámetros: 
        - df: Es un DataFrame con la información de la base de datos de los contratos menores.
        - nif: Es una cadena con el NIF del contratista.
        - seccion: Es una cadena con la sección del ayuntamiento que ordena el gasto.
        - años: Es una lista con los años. 
    Devuelve:
        Un diccionario con el número de contratos y el total facturado por la empresa con el nif dado a la sección dada durante los años indicados.
    """
    # Filtro de la empresa, la sección y los años
    df1 = df[(df['NIF'] == nif) & (df['SECCION'] == seccion) & (df['AÑO'].isin(años))]
    return {'Número de contratos': df1['IMPORTE'].count(), 'Total facturado':df1['IMPORTE'].sum()}
# Ejemplo
print(facturacion_empresa_seccion_años(df, 'B80176936', 'EMPRESA MUNICIPAL DE TRANSPORTES S.A.', [2018, 2019]))
    
    
In [14]:
    
def empresas_mayor_facturacion(df, años, n = 10):
    """
    Función que imprime una tabla con las n empresas que más han facturado durante los años indicados y genera un gráfico con esa información.
    Parámetros: 
        - df: Es un DataFrame con la información de la base de datos de los contratos menores.
        - años: Es una lista con los años. 
        - n: Es el número de empresas en la tabla (10 por defecto)
    """
    # Filtro de los años
    df1 = df[df['AÑO'].isin(años)]
    # Agrupar por empresas
    df1 = df1.groupby('NIF')['IMPORTE'].sum()
    # Ordenar descendentemente por importe
    df1 = df1.sort_values(ascending=False)
    # Obtener los n primeros y establecer el nombre de la empresa como índice.
    df1 = df1[:n].rename(lambda x: empresa(df, x))
    # Imprimirlos
    print(df1)
    # Inicializamos el gráfico
    fig, ax = plt.subplots(figsize=(6, 8))
    # Dibujar el diagrama de barras
    df1.plot(kind = 'bar', ax = ax)
    # Título del gráfico
    ax.set_title(str(n) + ' empresas con mayor facturación (años ' + str(años) + ')')
    # Título del eje x
    ax.set_ylabel('Importe total en €')
    # Ajustar los márgenes del gráfico
    plt.tight_layout()
    plt.gcf().subplots_adjust(bottom=0.6)
    # Guardamos el gráfico
    plt.show()
    return
# Ejemplo
empresas_mayor_facturacion(df, [2018,2019], n = 10)
    
    
    
In [15]:
    
def evolucion_empresas_mayor_facturacion(df, inicio, fin, n = 10):
    """
    Función que crea un gráfico con la evolución anual del total facturado por las n empresas con mayor facturación en un rango de años dado.
    Parámetros:
        - df: Es un DataFrame con la información de la base de datos de emisiones.
        - inicio: Es un entero con el año inicial.
        - fin: Es un entero con el año final.
        - n: Es el número de empresas en el gráfico (10 por defecto)
    """
     # Filtro de los años
    df1 = df[(df['AÑO'] >= inicio) & (df['AÑO'] <= fin)]
    # Agrupar por empresas
    df2 = df1.groupby('NIF')['IMPORTE'].sum()
    # Ordenar descendentemente por importe
    df2 = df2.sort_values(ascending = False)
    # Obtener la lista de los nifs de las n empresas con mayor facturación
    nifs = df2[:n].index
    # Filtrar las n empresas con mayor facturación en el rango de años
    df1 = df1[df1['NIF'].isin(list(nifs))]
    # Agrupar por años y empresas
    df1 = df1.groupby(['AÑO', 'NIF'])['IMPORTE'].sum()
    # Establecer como índice el nombre de la empresa
    df1 = df1.rename(lambda x: empresa(df, x), level = 1)
    # Inicializamos el gráfico
    fig, ax = plt.subplots(figsize=(10, 4))
    # Desagrupamos por empresas y generamos el gráfico de líneas
    df1.unstack().plot(legend = True, ax = ax)
    # Dibujar la leyenda fuera del área del gráfico
    plt.legend(loc='center left', bbox_to_anchor=(1.0, 0.5))
    # Título del gráfico
    ax.set_title('Evolución facturacion ' + str(n) + ' empresas con mayor facturación')
    # Título del eje x
    ax.set_ylabel('Importe anual en €')
    # Establecer las marcas del eje x
    ax.set_xticks(range(inicio, fin+1))
    # Ajustar los márgenes del gráfico
    # plt.tight_layout()
    # Guardamos el gráfico.
    plt.show()
    return
# Ejemplo
evolucion_empresas_mayor_facturacion(df, 2017, 2019)
    
    
In [16]:
    
def evolucion_facturacion_secciones(df, inicio, fin):
    """
    Función que crea un gráfico con la evolución de la facturacion anual por secciones en un rango de años dado.
    Parámetros:
        - df: Es un DataFrame con la información de la base de datos de emisiones.
        - inicio: Es un entero con el año inicial.
        - fin: Es un entero con el año final.
    """
     # Filtro de los años
    df1 = df[(df['AÑO'] >= inicio) & (df['AÑO'] <= fin)]
    # Agrupar por años y secciones
    df1 = df1.groupby(['AÑO', 'SECCION'])['IMPORTE'].sum()
    # Inicializamos el gráfico
    fig, ax = plt.subplots(figsize=(10, 4))
    # Desagrupamos por secciones y generamos el gráfico de líneas
    df1.unstack().plot(legend = True, ax = ax)
    # Dibujar la leyenda fuera del área del gráfico
    plt.legend(loc='center left', bbox_to_anchor=(1.0, 0.5))
    # Título del gráfico
    ax.set_title('Evolución facturacion por secciones')
    # Título del eje x
    ax.set_ylabel('Importe anual en €')
    # Establecer las marcas del eje x
    ax.set_xticks(range(inicio, fin+1))
    # Guardamos el gráfico.
    plt.show()
    return
# Ejemplo
evolucion_facturacion_secciones(df, 2017, 2019)