Taller evaluable sobre la extracción, transformación y visualización de datos usando IPython

Juan David Velásquez Henao
jdvelasq@unal.edu.co
Universidad Nacional de Colombia, Sede Medellín
Facultad de Minas
Medellín, Colombia

Instrucciones

Para realizar el taller:

En la carpeta 'Taller' del repositorio 'ETVL-IPython' se encuentran los archivos 'Precio_BolsaNacional($kwh)_'*'.xls' en formato de Microsoft Excel, los cuales contienen los precios históricos horarios de la electricidad para el mercado eléctrico Colombiano entre los años 1995 y 2017 en COL-PESOS/kWh. A partir de la información suministrada resuelva los siguientes puntos usando el lenguaje de programación Python.

Para el envío:

Al terminar el taller, y dentro de las fechas especificadas en la plataforma de OLADE, debe subir este archivo a su perfil de GitHub. En la plataforma debe copiar el enlace a este archivo, a modo de entregable.

Preguntas

1.-- Lea los archivos y cree una tabla única concatenando la información para cada uno de los años. Imprima el encabezamiento de la tabla usando head().


In [78]:
import pandas as pd
pd.read_excel('Precio_Bolsa_Nacional_($kwh)_1995.xlsx')


Out[78]:
Precio Bolsa Nacional ($/kWh) 1995 Unnamed: 1 Unnamed: 2 Unnamed: 3 Unnamed: 4 Unnamed: 5 Unnamed: 6 Unnamed: 7 Unnamed: 8 Unnamed: 9 ... Unnamed: 15 Unnamed: 16 Unnamed: 17 Unnamed: 18 Unnamed: 19 Unnamed: 20 Unnamed: 21 Unnamed: 22 Unnamed: 23 Unnamed: 24
0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
1 Fecha 0.000 1.000 2.000 3.000 4.000 5.000 6.000 7.000 8.000 ... 14.000 15.000 16.000 17.000 18.000 19.000 20.000 21.000 22.000 23.000
2 1995-07-20 NaN 1.073 1.073 1.073 1.073 1.073 1.073 1.073 1.074 ... 1.073 1.073 1.073 1.073 1.074 1.897 1.897 1.897 1.073 1.073
3 1995-07-21 1.073 1.000 1.000 1.000 1.000 1.000 5.000 6.000 6.000 ... 5.000 1.000 1.000 5.000 12.000 16.670 11.929 5.000 1.000 1.000
4 1995-07-22 1.073 1.073 1.000 1.000 1.000 1.073 1.303 1.303 1.303 ... 1.073 1.000 1.000 1.000 1.303 2.500 2.500 1.303 1.073 1.073
5 1995-07-23 1.073 1.000 1.000 1.000 1.000 1.000 0.100 1.000 1.000 ... 1.000 0.100 0.100 1.000 1.238 1.238 1.238 1.238 1.073 1.000
6 1995-07-24 1.000 1.000 0.990 1.000 1.000 1.073 3.000 3.000 3.000 ... 1.073 1.073 3.000 2.000 18.630 22.500 9.256 3.000 1.073 1.000
7 1995-07-25 0.990 0.990 0.989 0.990 0.990 1.073 1.263 1.263 1.263 ... 1.073 1.073 1.073 1.073 1.263 1.500 1.263 1.263 1.073 0.990
8 1995-07-26 0.500 0.500 0.500 0.500 0.500 0.990 1.073 1.073 1.073 ... 0.500 0.500 0.990 0.990 1.073 8.000 1.073 0.990 0.500 0.000
9 1995-07-27 0.500 0.500 0.500 0.500 0.500 0.500 0.500 0.500 0.500 ... 0.500 0.500 0.500 0.500 1.073 1.500 0.990 0.500 0.500 0.500
10 1995-07-28 0.000 0.000 0.000 0.000 0.000 0.463 0.463 1.000 0.463 ... 0.463 0.463 0.463 0.463 1.073 1.073 1.073 1.000 0.000 0.000
11 1995-07-29 1.000 1.000 0.000 0.000 1.000 0.000 1.070 1.070 1.070 ... 1.070 1.070 1.070 1.070 1.070 1.070 1.072 1.070 1.070 1.070
12 1995-07-30 1.072 1.000 0.000 0.000 0.000 0.000 0.100 1.000 1.072 ... 1.000 0.000 0.000 0.100 1.072 1.073 1.073 1.072 1.072 0.000
13 1995-07-31 0.000 0.000 0.000 0.000 0.000 1.000 1.073 0.000 0.000 ... 0.000 0.000 0.000 0.000 1.073 8.845 1.073 1.073 1.000 0.000
14 1995-08-01 0.000 0.000 0.000 0.000 0.000 1.070 1.073 0.000 1.070 ... 0.000 0.000 0.000 0.000 1.070 1.073 0.000 0.000 0.000 0.000
15 1995-08-02 1.073 1.073 1.073 1.073 1.073 1.073 1.100 1.073 1.073 ... 1.073 1.073 1.100 1.073 1.073 1.073 1.073 1.100 1.073 1.073
16 1995-08-03 1.073 1.073 1.073 1.073 1.073 1.100 2.000 2.000 2.000 ... 1.073 1.073 1.500 1.073 2.000 2.000 2.000 2.000 1.100 1.073
17 1995-08-04 1.073 1.073 1.073 1.073 1.073 2.000 2.000 2.000 2.000 ... 2.000 2.000 2.000 2.000 2.000 2.000 2.000 2.000 2.000 1.500
18 1995-08-05 2.000 2.000 2.000 1.073 2.000 2.500 2.500 2.558 2.558 ... 2.500 2.500 2.500 2.500 2.558 2.558 2.558 2.558 2.500 2.500
19 1995-08-06 3.000 1.073 1.073 1.073 1.073 3.000 3.000 3.000 3.200 ... 3.000 1.070 1.070 1.000 3.000 3.200 3.200 3.200 3.000 1.070
20 1995-08-07 3.000 3.000 3.000 1.073 3.000 3.000 3.500 3.500 3.700 ... 3.500 3.500 3.500 3.500 5.000 8.000 5.000 5.000 3.500 3.000
21 1995-08-08 3.000 3.000 3.000 3.000 5.800 7.000 7.000 9.000 8.000 ... 7.000 7.000 7.000 7.000 8.000 9.000 8.000 8.000 7.000 5.800
22 1995-08-09 10.000 10.000 10.000 10.000 10.000 13.788 17.000 15.000 15.000 ... 13.788 13.788 13.788 13.788 16.001 16.001 16.001 15.000 13.788 12.000
23 1995-08-10 18.000 18.000 18.000 18.000 18.000 18.000 21.000 21.000 21.000 ... 21.000 21.000 21.000 21.000 21.000 22.000 21.000 21.000 18.000 18.000
24 1995-08-11 12.000 6.000 6.000 6.000 22.600 25.000 25.000 25.000 25.000 ... 25.000 25.000 25.000 25.000 25.000 25.000 25.000 25.000 25.000 6.000
25 1995-08-12 30.000 15.000 1.074 15.000 17.500 30.000 30.000 31.000 40.000 ... 31.000 31.000 31.000 31.000 40.000 40.000 40.000 39.492 31.000 30.000
26 1995-08-13 35.000 18.000 17.000 18.000 18.000 24.600 32.000 39.492 40.000 ... 40.000 39.492 39.492 39.492 40.000 40.000 40.000 40.000 40.000 23.300
27 1995-08-14 17.000 1.074 12.000 12.000 17.500 39.492 40.000 40.000 40.000 ... 40.000 40.000 40.000 40.000 40.000 40.000 40.000 40.000 40.000 17.500
28 1995-08-15 1.074 1.074 1.074 1.074 1.074 17.500 20.000 20.000 20.000 ... 20.000 20.000 20.000 20.000 20.000 23.300 20.000 20.000 1.074 1.074
29 1995-08-16 1.074 1.074 1.074 1.074 1.074 8.000 12.000 8.000 12.000 ... 8.000 8.000 8.000 8.000 15.000 20.000 15.000 15.000 8.000 1.074
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
137 1995-12-02 120.000 120.000 120.000 120.000 120.000 120.000 73.000 117.112 117.112 ... 130.000 90.000 130.000 130.001 117.112 117.112 117.112 117.112 130.001 130.000
138 1995-12-03 130.001 130.001 130.001 130.001 130.001 130.001 117.112 130.000 124.627 ... 73.000 73.000 73.000 130.001 124.627 124.627 124.627 130.001 130.001 130.001
139 1995-12-04 160.001 160.001 135.000 130.002 160.000 135.001 132.001 132.001 132.001 ... 132.001 132.001 130.003 130.001 130.001 124.627 124.627 130.003 135.001 135.001
140 1995-12-05 78.620 78.620 24.500 40.882 70.734 137.413 137.413 137.413 137.413 ... 137.413 137.413 137.413 137.413 137.413 137.413 137.413 137.413 137.413 137.413
141 1995-12-06 22.300 22.300 22.200 22.200 22.400 22.400 147.070 147.070 147.070 ... 73.000 79.627 147.070 147.070 147.070 147.070 147.070 147.070 73.000 73.000
142 1995-12-07 31.716 31.716 31.716 31.716 31.716 31.716 100.000 156.248 156.248 ... 79.627 79.627 156.248 156.248 156.248 156.248 156.248 156.248 73.000 73.000
143 1995-12-08 20.000 15.468 15.468 14.000 15.468 20.000 22.400 22.400 32.913 ... 25.000 25.000 25.000 25.000 170.263 170.263 170.263 73.000 73.000 73.000
144 1995-12-09 79.627 22.400 22.400 22.400 22.400 32.913 170.600 170.600 170.600 ... 170.600 170.600 170.600 170.600 170.600 170.600 170.600 170.600 170.600 170.600
145 1995-12-10 172.660 88.524 40.000 79.627 79.627 36.900 30.000 172.660 172.660 ... 172.660 172.660 172.660 172.660 172.660 172.660 172.660 22.400 172.660 28.900
146 1995-12-11 30.000 20.000 20.000 20.000 36.900 22.300 36.900 179.730 179.730 ... 100.000 179.730 179.730 179.730 179.730 179.730 179.730 179.730 100.000 73.000
147 1995-12-12 40.000 40.000 40.000 40.000 40.000 40.000 73.000 179.001 179.001 ... 179.001 179.001 179.001 179.001 179.001 179.001 179.001 179.001 100.000 73.000
148 1995-12-13 60.000 55.000 55.000 50.000 55.000 60.000 120.000 120.000 120.000 ... 120.000 120.000 120.000 120.000 179.000 179.000 120.000 120.000 60.000 36.900
149 1995-12-14 20.000 20.000 20.000 20.000 20.000 20.000 40.000 55.000 60.000 ... 79.627 60.000 60.000 60.000 120.000 120.000 69.810 80.000 60.000 60.000
150 1995-12-15 20.000 16.640 15.000 15.000 20.000 20.000 60.000 60.000 60.000 ... 60.000 60.000 60.000 60.000 100.000 100.000 60.000 55.000 60.000 50.000
151 1995-12-16 15.000 15.000 15.000 15.000 15.000 15.000 60.000 60.000 60.000 ... 60.000 60.000 12.600 15.000 80.000 80.000 80.000 60.000 80.000 60.000
152 1995-12-17 9.890 1.500 1.500 1.500 1.500 1.500 10.000 13.000 13.700 ... 55.000 32.913 20.000 55.000 60.000 60.000 55.000 55.000 55.000 20.000
153 1995-12-18 20.000 15.000 15.000 20.000 30.000 55.000 55.000 55.000 55.000 ... 30.000 55.000 55.000 55.000 65.000 65.000 60.000 60.000 55.000 55.000
154 1995-12-19 40.000 40.000 40.000 40.000 40.000 60.000 65.000 65.000 65.000 ... 71.000 71.000 71.000 75.001 75.001 75.001 75.001 75.001 70.000 60.000
155 1995-12-20 40.000 40.000 40.000 40.000 40.000 60.000 60.000 60.000 60.000 ... 60.000 60.000 60.000 60.000 75.001 71.000 75.001 80.000 71.000 60.000
156 1995-12-21 40.000 30.000 30.000 30.000 40.000 60.000 70.000 70.000 70.000 ... 70.000 70.000 70.000 70.000 80.000 75.000 75.000 70.000 70.000 60.000
157 1995-12-22 15.000 15.000 15.000 15.000 15.000 18.465 40.000 60.000 60.000 ... 40.000 60.000 60.000 60.000 75.000 75.000 60.000 60.000 60.000 60.000
158 1995-12-23 13.700 1.074 1.074 1.074 12.650 15.000 20.000 20.000 20.000 ... 20.000 20.000 20.000 20.000 60.000 60.395 60.000 42.131 20.000 20.000
159 1995-12-24 40.000 35.000 30.000 21.000 21.000 32.700 9.700 15.000 18.465 ... 5.000 5.000 1.074 9.700 60.000 60.000 60.000 19.900 30.000 30.000
160 1995-12-25 18.465 15.000 1.074 1.074 1.074 1.074 1.074 1.074 1.074 ... 1.074 1.074 1.074 1.074 60.000 60.000 60.000 15.000 10.000 10.000
161 1995-12-26 19.900 15.000 15.000 15.000 16.640 25.000 15.000 15.000 25.000 ... 15.000 15.000 15.000 20.000 40.000 40.000 40.000 25.000 15.000 15.000
162 1995-12-27 15.000 15.000 15.000 15.000 15.000 15.000 15.000 15.000 15.000 ... 15.000 15.000 15.000 15.243 41.000 41.000 40.000 40.000 15.000 10.000
163 1995-12-28 14.900 14.900 14.900 14.900 14.900 15.000 25.000 25.000 25.000 ... 25.000 25.000 25.000 30.000 41.000 41.000 41.000 15.000 15.000 14.900
164 1995-12-29 11.990 11.990 11.990 11.990 15.000 15.243 13.600 30.000 30.000 ... 30.000 20.000 14.300 30.000 41.000 41.000 41.000 40.000 30.000 13.700
165 1995-12-30 13.500 12.000 12.000 12.000 9.700 13.500 14.300 18.000 30.000 ... 14.990 14.990 8.052 12.000 40.000 41.000 40.000 40.000 14.990 13.000
166 1995-12-31 15.000 14.990 14.990 14.990 14.990 14.990 14.990 12.000 13.000 ... 11.990 1.074 1.074 1.074 14.350 20.000 13.700 14.990 30.000 18.000

167 rows × 25 columns


In [79]:
x=[]
for n in range(1995,2018):
    if n<2000:
        skip=3
    else:
        skip=2
            
    nombrearchivo='Precio_Bolsa_Nacional_($kwh)_' + str(n)
    if n>=2016:
        nombrearchivo += '.xls'
    else:
        nombrearchivo += '.xlsx'
    y=pd.read_excel(nombrearchivo, skiprows=skip, parse_cols=24)
    x.append(y)
z=pd.concat(x)
print(z.head())
print(z.tail())


        Fecha      0      1      2      3      4      5      6      7      8  \
0  1995-07-20    NaN  1.073  1.073  1.073  1.073  1.073  1.073  1.073  1.074   
1  1995-07-21  1.073  1.000  1.000  1.000  1.000  1.000  5.000  6.000  6.000   
2  1995-07-22  1.073  1.073  1.000  1.000  1.000  1.073  1.303  1.303  1.303   
3  1995-07-23  1.073  1.000  1.000  1.000  1.000  1.000  0.100  1.000  1.000   
4  1995-07-24  1.000  1.000  0.990  1.000  1.000  1.073  3.000  3.000  3.000   

   ...       14     15     16     17      18      19      20     21     22  \
0  ...    1.073  1.073  1.073  1.073   1.074   1.897   1.897  1.897  1.073   
1  ...    5.000  1.000  1.000  5.000  12.000  16.670  11.929  5.000  1.000   
2  ...    1.073  1.000  1.000  1.000   1.303   2.500   2.500  1.303  1.073   
3  ...    1.000  0.100  0.100  1.000   1.238   1.238   1.238  1.238  1.073   
4  ...    1.073  1.073  3.000  2.000  18.630  22.500   9.256  3.000  1.073   

      23  
0  1.073  
1  1.000  
2  1.073  
3  1.000  
4  1.000  

[5 rows x 25 columns]
         Fecha           0           1           2           3           4  \
38  2017-02-08  116.070672  116.070672  116.070672  116.070672  116.070672   
39  2017-02-09  117.853455  125.852455  110.853455  110.853455  115.833455   
40  2017-02-10  133.799407  133.799407  117.799407  117.799407  125.699407   
41  2017-02-11  132.603212  131.604212  131.604212  131.604212  131.604212   
42  2017-02-12  141.109843  141.109843  141.109843  139.610843  128.110843   

             5           6           7           8     ...              14  \
38  116.070672  119.070672  119.070672  126.570672     ...      141.570672   
39  125.852455  125.852455  125.852455  125.853455     ...      132.353455   
40  133.799407  133.799407  133.799407  161.798407     ...      206.799407   
41  131.604212  132.603212  132.603212  132.603212     ...      162.604212   
42  162.010843  128.110843  128.110843  141.109843     ...      141.109843   

            15          16          17          18          19          20  \
38  141.570672  126.570672  126.570672  141.570672  249.215672  151.070672   
39  132.353455  125.853455  125.853455  202.853455  206.853455  182.353455   
40  206.799407  161.798407  161.798407  221.798407  206.799407  221.799407   
41  162.604212  162.604212  162.604212  163.504212  207.604212  163.104212   
42  141.109843  141.109843  141.109843  151.110843  162.010843  151.110843   

            21          22          23  
38  126.570672  126.570672  116.070672  
39  125.853455  125.852455  117.853455  
40  161.798407  161.798407  133.799407  
41  162.604212  162.604212  132.603212  
42  151.110843  141.109843  141.109843  

[5 rows x 25 columns]

2.-- Compute e imprima el número de registros con datos faltantes.


In [80]:
len(z)


Out[80]:
7962

In [7]:
z.size


Out[7]:
199050

In [81]:
len(z)-len(z.dropna())


Out[81]:
28

3.-- Compute e imprima el número de registros duplicados.


In [82]:
len(z)-len(z.drop_duplicates())


Out[82]:
67

In [83]:
len(z.drop_duplicates())


Out[83]:
7895

In [84]:
len(z.dropna())


Out[84]:
7934

4.-- Elimine los registros con datos duplicados o datos faltantes, e imprima la cantidad de registros que quedan (registros completos).


In [85]:
w=z.dropna().drop_duplicates()
len(w)


Out[85]:
7875

In [86]:
len(w)-len(w.drop_duplicates())


Out[86]:
0

In [87]:
len(w)-len(w.dropna())


Out[87]:
0

5.-- Compute y grafique el precio primedio diario.


In [19]:
prom = w.mean(axis=1)
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
%matplotlib inline
plt.xlabel('Dias')
plt.ylabel('$/kWh Promedio')
plt.title('Precios Promedios Diarios')
plt.bar(range(len(prom)),prom)
plt.show()


6.-- Compute y grafique el precio máximo por mes.


In [88]:
q=[]
for n in range(len(w['Fecha'])):
    q.append (str(w.iloc[n,0])[0:7])
w['mes']=q
maximomes = w.groupby('mes').max()
maximomes= maximomes.max(axis=1)
plt.xlabel('Meses')
plt.ylabel('$/kWh Promedio')
plt.title('Precios Maximos Mensuales')
plt.bar(range(len(maximomes)),maximomes)
plt.show()



In [ ]:

7.-- Compute y grafique el precio mínimo mensual.


In [92]:
minimomes = w.groupby('mes').min()
minimomes = minimomes.min(axis=1)
plt.xlabel('Mensual')
plt.ylabel('$/kWh Promedios')
plt.title('Precios Minimo Mensual')
plt.bar(range(len(minimomes)),minimomes)
plt.show()


8.-- Haga un gráfico para comparar el precio máximo del mes (para cada mes) y el precio promedio mensual.


In [93]:
promediomes = w.groupby('mes').mean()
promediomes= promediomes.mean(axis=1)
plt.xlabel("Meses")    
plt.ylabel("$/kWh")
plt.plot(pd.Series(promediomes).values,label="Promedio")        
plt.plot(pd.Series(maximomes).values, label="Máximo")  
plt.legend(loc="center left")


Out[93]:
<matplotlib.legend.Legend at 0x1ba4fb307b8>

9.-- Haga un histograma que muestre a que horas se produce el máximo precio diario para los días laborales.


In [94]:
from datetime import datetime, date, time, timedelta
import calendar

fecha=[]
fecha=w['Fecha']
w['Fecha']=pd.to_datetime(w['Fecha'], format="%Y-%m-%d")
w['Dia']=w['Fecha'].dt.weekday_name

Lab = w['Dia'].isin(['Monday','Tuesday','Wednesday','Thursday','Friday'])
Lab = w[Lab]
indicador = ['{}'.format(n) for n in range(len(Lab))]
Lab.index = indicador

t=[]                                
for n in range(len(Lab)):
    x = pd.Series(Lab.loc[str(n)]).values[1:25]
    t.append ([i for i, e in enumerate(x) if e == max(x)])
    a=[]                     
for n in range(len(t)):
    for i in range (len(t[n])):
        a.append(t[n][i])
rep=[]    

for n in range (24):
    rep.append(a.count(n))
plt.xlabel("Horas")
plt.ylabel("$/kWh")
plt.bar(range(24),rep,color='r',width = 1)
plt.show()


10.-- Haga un histograma que muestre a que horas se produce el máximo precio diario para los días sabado.


In [95]:
Sab = w['Dia'].isin(['Saturday'])
Sab = w[Sab]

indicador = ['{}'.format(n) for n in range(len(Sab))]
Sab.index = indicador
 

s=[]                               
for n in range(len(Sab)):
    x = pd.Series(Sab.loc[str(n)]).values[1:25]
    s.append ([i for i, e in enumerate(x) if e == max(x)])
    
    a=[]                     
for n in range(len(s)):
    for i in range (len(s[n])):
        a.append(s[n][i])
rep=[]    

for n in range (24):
    rep.append(a.count(n))
plt.xlabel("Sabado")
plt.ylabel("$/kWh")
plt.bar(range(24),rep,color='r',width = 1)
plt.show()


11.-- Haga un histograma que muestre a que horas se produce el máximo precio diario para los días domingo.


In [96]:
Sab = w['Dia'].isin(['Sunday'])
Sab = w[Sab]

indicador = ['{}'.format(n) for n in range(len(Sab))]
Sab.index = indicador
 

s=[]                                
for n in range(len(Sab)):
    x = pd.Series(Sab.loc[str(n)]).values[1:25]
    s.append ([i for i, e in enumerate(x) if e == max(x)])
    
    a=[]                     # Este Fragmento hace una matriz de la matriz u que contenia horas en que el maximo se repetia.
for n in range(len(s)):
    for i in range (len(s[n])):
        a.append(s[n][i])
rep=[]    

for n in range (24):
    rep.append(a.count(n))
plt.bar(range(24),rep,color='r',width = 1)
plt.show()


12.-- Imprima una tabla con la fecha y el valor más bajo por año del precio de bolsa.


In [97]:
A=[]
nmatriz=w
for n in range(len(nmatriz['Fecha'])):
    A.append (str(nmatriz.iloc[n,0])[0:4])
nmatriz['ano']=A
minimoano = nmatriz.groupby('ano').min()
minimoano= minimoano.min(axis=1)
minimoano


Out[97]:
ano
1995     0.000000
1996     0.000000
1997    10.882310
1998    13.847330
1999    18.359530
2000    21.531167
2001    24.822879
2002    26.777682
2003    37.013438
2004    32.252998
2005    27.581415
2006    26.714797
2007    30.173824
2008    29.199135
2009    32.892503
2010    32.024957
2011    33.291100
2012    34.988099
2013    40.415346
2014    38.941951
2015    46.791501
2016    61.100689
2017    61.356315
dtype: float64

13.-- Haga una gráfica en que se muestre el precio promedio diario y el precio promedio mensual.


In [98]:
indicador = ['{}'.format(n) for n in range(len(w))]
w.index = indicador

In [99]:
promediomes=[]
for n in range (len(w)):
    y=w.groupby('mes')
    f=w.loc[y.groups[w['mes'][n]]].mean()
    f=f.mean()
    promediomes.append(f)
    
plt.xlabel("Meses")    
plt.ylabel("$/kWh")
plt.plot(pd.Series(promediomes).values,label='Promedio mes')        
plt.plot(pd.Series(prom).values,label="Promedio diario") 
plt.legend(loc="center left")
plt.show()