You are on page 1of 22
Unipython Q (https://unipython.com/) ANALISIS DE Mend Do Blog E SERIES TEMPORALES CON LA LIBRERIA PANDAS Originalmente, las herramie! financieras. Las robustas y fi ntas de la libreria Pandas, fueron desarrolladas para series temporales lexibles estructuras de datos en Pandas pueden ser aplicadas a series temporales en cualquier dominio, incluyendo negocios, ciencia, Ingenieria, salud publica y muchos otros. Con esta herramienta se pu jeden organizar, transformar, analizar y visualizar datos en cualquier nivel de granularidad (examinar los detalles durante periodos especificos de interés y extrapolarlos para explorar variaciones en dife rentes escalas de tiempo, como agregaciones mensuales o anuales, patrones recurrentes, y tendencias a largo plazo). Te invitamos a nuestro Curso Python de Anilisis de Datos: Curso de Anilisis de Datos (https://u ‘Reserva tu plaza antes del 15 de Marzo (https://bit.ly/3dl70)X) En la definicién mas amplia, una serie temporal es cualquier conjunto de datos donde los valores se miden en diferentes puntos en el tiempo. Muchas series temporales son medidas uniformemente con una frecuencia especifica, por ejemplo, las mediciones climaticas por hora, los recuentos diarios de visitas a sitios web o las ventas totales mensuales. Dichas series también pueden estar espaciadas irregularmente, por ejemplo, los datos con marca de tiempo (timestamp) en el registro de eventos (logs) de un sistema informatico o un historial de llamadas de emergencia al 911, Las herramientas de series temporales de Pandas se aplican igualmente bien a cualquier tipo de serie temporal. Este tutorial se enfocard principalmente en data wrangling y en los aspectos de visualizacién del analisis de las series temporales. Trabajando con una serie temporal de datos de energia eléctrica, se observara la forma en que técnicas como la indexacién basada en el tiempo, el remuestreo y las ventanas deslizantes pueden ser de gran ayuda en la exploracién de variaciones en la demanda de electricidad y el suministro de energia renovable a lo largo del tiempo. Los siguientes temas seran cubiertos: Conjunto de datos: Open Power Systems Data, Estructuras de datos de series temporales. Indexacion basada en el tiempo. Visualizacién de datos de series temporales. Estacionalidad. Frecuencia. Remuestreo. Ventanas deslizantes, Tendencias. Se utilizaré Python 3.6, Pandas, matplotlib y seaborn. Para aprovechar al maximo este tutorial, se recomienda estar familiarizado con los conceptos basicos de pandas y matplotlib. Conjunto de Datos: Open Power Systems Data En este tutorial, se trabajar con series temporales diarias de Open Power System Data (OPSD) para Alemania, que ha estado expandiendo rapidamente su produccién de energia renovable en los tltimos afios. El conjunto de datos incluye los consumos de electricidad totales, la produccién de energia edlica y la produccién de energia solar en todo el pais para 2006-2017. Los datos se encuentran aqui (https://unipython.com/wp-content/uploads/2019/08/opsd_germany_daily.csv). El consumo y produccién de la electricidad estan expresados en GigaWatts-Hora(GWh). Las columnas del archivo de datos contienen la siguiente informacién: Date: La fecha (formato aaaa-mm-dd) Consumption: Consumo de electricidad en GWh. Wind: Produccién de energia edlica en GWh. Solar: roduccién de energia solar en GWh Wind+Solar: Suma de la produccién de energia eélica y solar en GWh. Se explorard cémo el consumo y la produccién de electricidad en Alemania ha variado alo largo del tiempo, utilizando las herramientas de las series temporales de Pandas para responder las siguientes preguntas: @Cudndo es el consumo de electricidad tipicamente mas alto y mas bajo? ¢Cémo varia la produccién de energfa edlica y solar con las estaciones del afio? @Cusles son las tendencias a largo plazo en el consumo de electricidad, energ(a solar y energ(a edlica? eCémo se compara la produccién de energfa edlica y solar con el consumo de electricidad, y cémo ha cambiado esta relacién con el tiempo? Estructuras de Datos de Series Temporales Antes de comenzar el andlisis de los datos de OPSD, es necesario conocer las principales estructuras de datos de Pandas para trabajar con fechas y horas. En Pandas, un solo punto en el tiempo se representa como una marca de tiempo (timestamp). La funcién to_datetime( crea marcas de tiempo a partir de cadenas de caracteres en una amplia variedad de formatos de fecha/hora. A continuacién se importard Pandas y se convertira algunas fechas y horas en marcas de tiempo (timestamps). >>> import pandas as pad >>> pnd.to_datet \d.to_datetine (19/8/1993") Como puede ser observado, la funcién to_datetime() infiere automaticamente un formato de fecha/hora basado en la entrada, En el ejemplo anterior, se supone que la fecha ambigua ‘9/8/1993’ es mes/dia/afio y se interpreta como el 8 de septiembre de 1993. Alternativamente, se puede utilizar el parametro dayfirst (primero el dia) para decirle a Pandas que interprete la fecha como 9 de agosto de 1993. 1, | >9> pnd.to_datet Timestamp "1993-08: 8/1993", dayfirst: 0:00:00) 9 Si se suministra un arreglo de cadenas de caracteres como entrada para la funcién to_datetime(), esta devuelve una secuencia de valores de fecha/hora en un objeto Datetimeindex, que es la estructura de datos central que alimenta gran parte de la funcionalidad de las series temporales de Pandas. 1. | 55> pnd.to_datetine ({*2019 imetndex ({"2015 18", "9/8/1983", *12/15/2003"1) + "1393-08-08", '2003-12-15"), aty, ime6a[ns]', freq-None! En el Datetimeindex anterior, el tipo de datos datetime64[ns] indica que los datos subyacentes se almacenan como enteros de 64 bits, en unidades de nanosegundos (ns). Esta estructura de datos permite que pandas almacene de forma compacta grandes secuencias de valores de fecha/hora y realice operaciones vectorizadas de manera eficiente utilizando arreglos NumPy datetime64, Si se est trabajando con una secuencia de cadenas de caracteres en el mismo formato de fecha/hora, se puede especificar explicitamente con el parametro format (formato). Para conjuntos de datos muy grandes, esto puede acelerar en gran medida el rendimiento de la funcién to_datetime() en comparacién con el comportamiento predeterminado, donde el formato se deduce por separado para cada cadena de caracteres individual. Se puede usar cualquiera de los cédigos de formato de las funciones strftime() y strptime() en el médulo datetime incorporado de Python. El siguiente ejemplo utiliza los cédigos de formato %m (mes numérico), %d (dia del mes) y Sy (afio de 2 digitos) para especificar el formato. "1, deype='datetiness 1. | 55> pnd. to_datetime ({118/07/19", 19/8/93" 2. Datetimetndex({'2019-07-18", 1993-98-09", * ‘Ademis de los objetos Timestamp y Datetimeindex que representan puntos individuales en el tiempo, pandas también incluye estructuras de datos que representan duraciones y perfodos. A continuacién, se utilizar Datetimeindexes, la estructura de datos mas comtn para series temporales de pandas. Creacién de un DataFrame de Series Temporales Para trabajar con datos de series temporales en pandas, se utiliza un Datatimeldex de fecha/hora como el indice para nuestro marco de datos (DataFrame). Veamos cémo hacer esto con nuestro conjunto de datos OPSD, Primero, usamos la funcién read_csv() para leer los datos en un DataFrame, y luego mostrar su forma. 1. 35> oped dia read_cov(*opad_garmany datly.cav! 3. (4383, 5) El DataFrame tiene 4383 filas, que abarcan desde el 1 de enero de 2006 hasta el 31 de diciembre de 2017. Para ver el los datos, se utilizan los métodos head) y taill) que muestran las primeras y las Ultimas filas del documento. >>> opad_dia head (4) Date Consume Solar Winds: 1 3. 9 2006-01- 1069.124 NaN Naw 4 2006-01~ 1380.521 Nan NaN 6.3 2006-01-04 -1657.217 NaN Nady 7. >>> opsd_dia.tait (4) 8 Date Consurption Wind 9. 4379. 2017-12-28 398 506.426 ao. 4380. 2017-12-29 ai. 4381 2017-12-30 De esta forma se abren archivos y se puede hacer consultas. Para definir el indice que se desea, se utilizan los parametros index_col y parse_dates de la funcién read_csv0. Esto suele ser un atajo titil = pd.read_cev("epsd_gerrany daily.cev’, 1 2. >>> oped dia. index 4. "2006-01-05", 5. *2006-01-09", 6 F. *2on7=12-22", *2027-12-23", "2017-12-24", *2017-12~ 8. "2027-12-26", 2017-12-27", "2027-12-28", *2017-12-, 9. *2017-12-20", 2017-12-31], 10. dtype-'datetiness[na}*, name-'Date', Length-4383, freq-None) Ya que el indice de el DataFrame es un indice de fecha y hora, se puede utilizar la indexacién basada en el tiempo de Pandas para organizar y analizar datos Otro aspecto util del indexado de fecha y hora es que los componentes de fecha/hora individuales estan disponibles como atributos, como afio (year), mes (month), dia (day), entre otros. Se agregardn algunas columnas mas a opsd_dia, que contienen el afio, mes y nombre del dia de la semana *] = opsd_dia.index. year 1 2 *] = opsd_dia.index.mont 3. "Dia ] = oped_dia.index.weekday_nane 4 5 Solar WindtSolac Ano Mae bia 7 NaN Naw 8 saturday 8 79.666 93.371 a 9 NaN NaN NaN e 10. 229° 160.641 242.870 ° ue NaN NaN 6 12 97.155 24.685 2 a 22.117 NaN Naw 7 Indexaci6n basada en el Tiempo Una de las caracteristicas mas poderosas y convenientes de las series temporales de Pandas es la indexacién basada en el tiempo: el uso de fechas y horas para organizar y acceder de forma intuitiva a los datos. Con la indexacién basada en el tiempo, se pueden utilizar cadenas de caracteres con formato de fecha/hora para seleccionar datos en el DataFrame con la funcién loc. Esto funciona de manera similar a la indexacién basada en etiquetas estandar, pero con algunas caracteristicas adicionales. Por ejemplo, se pueden seleccionar datos de un solo dia utilizando una cadena de caracteres como ‘2015-07-18'. 1.) 59> opsd_dia-lee('2015-07-28") 3. i 4. Solas 6. Bho 8. bia saturday 9. Name: 2018-07-18 09:00:00, dtype: object También es posible seleccionar un intervalo, como ‘2013-08-15''2013-08-20'. El intervalo seleccionado es un intervalo cerrado. 1. 55> eped_dia.1oe{'2013-08-15": 120) 4 49 2013 Y 5 690 2013 y 6 187 201s ¥ 7 09) 2013 y 8. 2013 y 9 2013 y Otra caracteristica muy util de las series temporales de pandas es la indexacién de cadenas de caracteres parciales, donde se pueden seleccionar todas las fechas/horas que coincidan parcialmente con una cadena de caracteres dada. Por ejemplo, se puede seleccionar todo el afio 2008 con opsd_daily.loc ['2008'], 0 todo el mes de marzo de 2009 con opsd_daily.loc ['2009-03']. 2 Consumption Wind Ako Mes Dia 3. bate 4. 2009-03-01 108.937 Naw Naw, 3 6. 1427.385 NaN NaN 3 1423.119 NaN NaN 3 Wednesday 8 1432.391 NaN NaN 3 Thursday 3. 1401.981 NaN NaN 3 iday 10. 1190.240 NaN NaN 3 day rs 1a4.724waN NaN 3 Sunday 2. Nex Wax 3 Monday a NaN aN 3 Tuesday a4 Nay Nay 3. Wednesday 16. NaN NaN 3 day 17, Nay NaN 3 day 18 Nan NaN 3 Sunday a9 Nan NaN 3 Monday 20 NaN NaN 3 Tuesday 2. NaN Nay 3. Nednesday 22. NaN aN 3 24 NaN Nay 3 25. Nan NaN 3 ar. NaN NaN 3 Tuesday 28. Naw 3. Wednesday 29 Nan aN 3 Thuraday 30. NaN aN 5 day a. NaN NaN 3 day 22 NaN Nay 3 Sunday 3 NaN NaN Naw 3 Tuesday Visualizacién de Datos de Series Temporales Con pandas y matplotlib, se pueden visualizar facilmente nuestros datos de las series temporales. En esta seccién, se cubrir4n algunos ejemplos y algunas personalizaciones utiles para graficos de series temporales. Se recomienda el uso de Jupyter Notebooks (https://jupyter.org/) para visualizar los graficos. Primeramente, es necesario importar matplotlib. 1. | Amport matplotiib.pyplot ag mplt # Esta funcién oe utillzada para mostrar les graficos Se utilizaré seaborn para el estilo de los graficos y se ajustar4 el tamafio de figura predeterminado a una forma més adecuada para las graficas de series temporales. 1. Amport seaborn as sba sbn.set (re=[ "figure. figsize': (20, 91) Se creard un grafico de Iineas de la series temporales completas del consumo diario de electricidad de Alemania, utilizando el método plot(). ve00 1200 1200 1000 00 2008 2008 aw m2 as 26 Date Se puede observar que el método plot() elige buenas escalas y etiquetas para el eje x, lo cual es util. Sin embargo, con tantos datos, el trazado de linea est abarrotado y es dificil de leer. Se pueden trazar los datos como puntos en su lugar, y también mirar las series temporales de la produccién de energia solar (Solar) y edlica (Wind) ol_grat = [*Consunpt or e rue) for eje in cies | dialcol_graf 10,10) , subpl ‘\ 7 ‘Consumption Solar Consume Diario (GIWh| 8 8 vn corona aa B28 %o e Co Las tres series temporales muestran claramente la periodicidad, a menudo llamada estacionalidad en el anilisis de las series temporales, en la que un patrén se repite una y otra vez en intervalos de tiempo regulares. Las series temporales de consumo (Consumption), produccién de energia solar (Solar) y produccién de energia edlica (Wind) oscilan entre valores altos y bajos en una escala de tiempo anual, que se corresponde con los cambios estacionales del clima a lo largo del afio. Sin embargo, la estacionalidad en general no tiene que corresponder con las estaciones meteorolégicas. Por ejemplo, los datos de ventas minoristas a menudo muestran una estacionalidad anual con un aumento de las ventas en noviembre y diciembre, lo que lleva a las vacaciones. La estacionalidad también puede ocurrir en otras escalas de tiempo. El grafico anterior sugiere que puede haber alguna estacionalidad semanal en el consumo de electricidad de Alemania, correspondiente a los dias de semana y fines de semana. Se trazar4 la serie temporal en un solo afio para investigar més a fondo fe = opsd_dia.1oc{ "2016", *Consunp: set_ylabel (‘Consumo Diario (Gin) ") 1700, 800 z 400 800 Consumo Diaio(GWh) 100 dun Feb Mer Apr Myung Sept Hye ae Ahora se pueden notar claramente las oscilaciones semanales, Otra caracteristica interesante que se hace evidente a este nivel de granularidad es la dréstica disminucién en el consumo de electricidad a principios de enero y finales de diciembre, durante las vacaciones. Para observar con mayor detalle, se presentaré el grAfico de Enero y Febrero. oc{"2016-01": "2016-02", ‘Consumption’ .plot (marker="0", Linestyls ("Consumo Diario (GHh) ") 400 1300 Consume Diario (Gin) ‘200 100 on Fee Paty Como se esperaba, el consumo es més alto en los dias de semana y més bajo los fines de semana. El cédigo final de los graficos de esta parte es: ler y 2do Grafico de Visualizacién de Datos de Series Temporales ‘Import pandas as pnd import mat Amport sesborn as opsd_dia = prd.read_cev(‘oped_germany_daily.c: __atee-True) sbn.set (re~( "figure. thasize': (10, 9}) 2 3. 16. £igsize=(10, 10), subploce-tewe) eno Diario (Gah) ") 3er Grafico de Visualizacién de Datos de Series Temporales |) parse_dates-teue) ) parse_dates-True) {dia = pnd.read_cav(‘oped_geemany_< sbn.set (ro=( "figure. figsize': (10, $19) 4 kto Gratico e3¢ = opsd_dia.1oct"2016-02': 2016-02", *Consumption'] .plot (marker="o", Linestyle="=") Estacionalidad A continuacién, se profundizaré en la estacionalidad de los datos con diagramas de caja, utilizando la funcién boxplot() de seaborn para agrupar los datos por diferentes periodos de tiempo y mostrar las distribuciones de cada grupo. Primero se agrupan los datos por mes, para visualizar la estacionalidad anual. 1800 ‘Consumption aT e es 8 = 1 t 2 a & . = a 7 el; 3 Le =] : nt : = 200 ’ . ‘ wa ba as Fao 1s t | + - ws Estos diagramas confirman la estacionalidad anual que se observé en las gréficas anteriores y brindan algunas ideas adicionales: ‘Aunque el consumo de electricidad es generalmente més alto en invierno y més bajo en verano, la mediana y los dos cuartiles mas bajos son mds bajos en diciembre y enero en comparacién con noviembre y febrero, probablemente debido a que las empresas estan cerradas durante las vacaciones. Esto se observé en la serie temporal del afio 2016, y el diagrama de caja confirma que este es un patrén constante alo largo de los afios. Si bien la produccién de energfa solar y eélica muestran una estacionalidad anual, las distribuciones de energia edlica tienen muchos més valores atipicos, lo que refleja los efectos ocasionales de las velocidades extremas del viento asociadas con las tormentas y otras condiciones meteorolégicas transitorias. Acontinuacién, se agruparén las series temporales de consumo de electricidad por dia de la semana, para explorar la estacionalidad semanal. 1. | abn.boxplot (data-opsd_dia, x='Dia', y-'Consunption') 1600 | = Y : ! J corsur ‘000 . , ‘ al ’ 00 Sunday Monay = Tuescay—Wedhiesday Thursday day soturay Da Como se esperaba, el consumo de electricidad es significativamente mayor en los dias de semana que en los fines de semana. Los valores atipicos bajos en los dias de semana son presumiblemente durante los dias festivos. Esta seccién ha proporcionado una breve introduccién a la estacionalidad de las series temporales. Como se verd més adelante, la aplicacién de una ventana deslizante a los datos también puede ayudar a visualizar la estacionalidad en diferentes escalas de tiempo. Otras técnicas para analizar la estacionalidad incluyen diagramas de autocorrelacién, que trazan los coeficientes de correlacién de las series temporales consigo mismas en diferentes intervalos de tiempo. Las series temporales con una fuerte estacionalidad a menudo se pueden representar bien con modelos que descomponen la sefial en estacionalidad y en una tendencia a largo plazo, y estos modelos se pueden usar para pronosticar los valores futuros de las series temporales. Un ejemplo simple de tal modelo es la descomposicién estacional clasica. Un ejemplo més sofisticado es el modelo Prophet de Facebook, que utiliza el ajuste de curvas para descomponer las series de tiempo, teniendo en cuenta la estacionalidad en multiples escalas de tiempo, efectos de vacaciones, puntos de cambio abruptos y tendencias a largo plazo. El cédigo final de los graficos de esta parte es: ler Grafico de estacionalidad import pans: Amport matplot Amport seaborn ae sb: as pnd dl. 2ad_eav ("op a[tMes') = opsd_dia-index.non 20, 5)3) subplots (3, 1, figsize=(11, 10), eje an zip ({*Consunp: font, "Solar", "Wi Mea", yenonbre, ax-e16) 16, aje-n -_xilabel('') 2do Grafico de estacionalidad 1. import pandas as pnd 2. dmport matplotiib.pyplot ae mplt 3, import seaborn as. sbi 4 5. ed_dia = pd.read_cav (‘opsd_germany daily.cev', index col-0, parse dates-teue) 6. opsd_dial'Dia') = oped dia. index. weekday name n 5. sbn.set (re-(*Figure.figsize': (10, 5)}} a, x='Dia', y="Consumption') Frecuencias Cuando los datos de una serie temporal estén distanciados en el tiempo de forma uniforme (por ejemplo, cada semana hay una baja en el consumo de corriente eléctrica en una localidad determinada,), la serie puede asociarse con una frecuencia en pandas. Por ejemplo, con la funcién date_range() se creara una secuencia de fechas espaciadas uniformemente desde 2015-09-15 hasta 2015-09-20 a una frecuencia diaria. 1.) 99> pnd 2. Datetimetnde: +, "2018; : 3. "2025-1 + freq='D") El Datetimeindex resultante tiene un atributo de frecuencia (freq) con un valor de ‘D’, que indica la frecuencia diaria. Las frecuencias disponibles de pandas incluyen cada hora ('H), calendario diario (D), diario de negocios ('B), senanal (W), mensual (‘M), trimestral ((Q), anual (‘A), y muchos otros. Las frecuencias también se pueden especificar como miltiplos de cualquiera de las frecuencias base, por ejemplo, ‘SD’ por cada cinco dias. Como ejemplo secundario, se creara otro rango de fechas con frecuencia de una hora, especificando la fecha de inicio y el numero de periodos en lugar de la fecha de inicio y fecha de finalizacién. Acontinuacién, se revisaré el Datatimeindex de la serie de tiempo opsd_dia. 1-01", "20 01-05", *20 01-09", 2006-01-10", ength=4383, freq-None) Se puede ver que no tiene frecuencia (freq=None). Esto tiene sentido, ya que el indice se creé a partir de una secuencia de fechas en el archivo CSV, sin especificar frecuencia para la serie temporal. Si se sabe que los datos deben estar en una frecuencia especifica, se puede usar el método asfreq)) de DataFrame para asignar una frecuencia. Si falta alguna fecha/hora en los datos, se agregaran nuevas filas para esas fechas/horas, que estén vacias (NaN) o se llenan de acuerdo con un método de llenado de datos especifico, como el llenado hacia adelante o la interpolacién. Para conocer el funcionamiento de esto, se creard un nuevo DataFrame que contenga solo los datos de Consumo del 2, 4 y 6 de marzo de 2010. 2010-0. o10-03-; 2010-03-06 Ahora con el método asfreq() se convertira el DataFrame a una frecuencia diaria, con una columna con datos incompletos y una columna con los datos luego de ser ingresados con forward fill (fill. freq("D", method="f£i11") 2010-03-08 2ore- 2010- En la columna de consumo, "Consumption", se encuentran los datos originales, con un valor de NaN para cualquier fecha que faltaba en el DataFrame de muestra (muestra_consumo). En la ultima columna (Consumption - Datos Ilenos), los datos faltantes se han “rellenado hacia adelante’, lo que significa que el Ultimo valor se repite en las filas faltantes hasta que se produce el siguiente valor no faltante. Si se est realizando algtin andlisis de series temporales que requiera datos espaciados uniformemente sin faltas, es recomendable utilizar asfreq() para convertir series temporales a la frecuencia especificada y completar los datos que falten con el método apropiado. Remuestreo Amenudo es util aplicar el remuestreo en datos de series temporales a una frecuencia mas baja o mas alta, El remuestreo a una frecuencia més baja (submuestreo) generalmente implica una operacién de recoleccién 0 sumatoria, por ejemplo, calcular la distancia recorrida por un autobuis en un mes, tomando las distancias que recorrié cada dia de dicho mes. El remuestreo a una frecuencia més alta (sobremuestreo) es menos comin y, a menuda, implica la interpolacién, aproximacién u otro método de llenado de datos. Esta seccién estara centrada en el submuestreo, y como puede ayudar en el analisis de los datos de OPSD en varias escalas de tiempo. Se utilizar el método resampled) del DataFrame, que divide el Datetimeindex en intervalos de tiempo y agrupa los datos por intervalo de tiempo. El método resample) devuelve un objeto Resampler, similar al objeto de pandas GroupBy. Luego se puede aplicar un método de agregacién como meand (calcula la media), medianQ (calcula la mediana), sum9 (calcula la suma), entre otros, al grupo de datos para cada intervalo de tiempo. Se aplicara remuestreo a los datos para la media semanal de una serie temporal. 1 /tWindsSolar'] 2 Fesample ("#") -nean() 3. >>> media_opad_senai 4 6. 2006-01-01 1069.18¢000 NaN NaN, naw 8. 2006-01-15 1486.730286 NaN NaN. Naw La primera, etiquetada 2006-01-01, contiene la media de todos los datos contenidos en el intervalo de tiempo 2006-01-01 hasta 2006-01-07. La segunda fila, etiquetada 2006-01-08, contiene los datos promedio para el intervalo de tiempo 2006-01-08 hasta 2006-01-14, y asi sucesivamente. De forma predeterminada, cada fila de la serie temporal submuestreada se etiqueta con el borde izquierdo del intervalo de tiempo. Por construccién, la serie de tiempo semanal tiene 1/7 tantos puntos de datos como las series temporales diarias, Se puede confirmar esto comparando el nlimero de filas de los dos DataFrames. >>> oped dia.shape(0] 4382 >>> media_opad_senanal.shape(0 62 Se trazaran las series temporales diarias y semanales para la energia solar (Solar) juntas en un solo periodo de seis meses para compararlas. piel, final = *2025-06", 2015-12" inpiote ( nat, "Solar" ] ;marker: pLinewidth=0.5, abel keraize=s, label='senanal") ién Solar (Geh)") e.set_ylabel ("F zo é & 3 2158-06 15.07 NSB ISD NHS IO IS S42 ate oF Se puede observar que las medias para las series temporales semanales son mas suaves que para las series temporales diarias porque se ha promediado una variabilidad de frecuencia més alta en el remuestreo, ‘Ahora se har nuevamente un remuestreo a los datos a una frecuencia mensual, agregando sumas totales en lugar de la media. A diferencia de la agregacién con meanQ), que establece la salida en NaN para cualquier perfodo con todos los datos faltantes, el comportamiento predeterminado de sum() devolverd la salida de 0 como la suma de los datos faltantes. Se utilizar el parémetro min_count para cambiar este comportamiento. >>> opsd_mensual = opsd_dia{colunnas] . resample (*M*) -sum(nin_count=28) >>> opad_mensual.head (2) 2006-01~ Se puede notar que los datos remuestreados mensualmente estén etiquetados con el final de cada mes (el limite derecho del intervalo), mientras que los datos remuestreados semanalmente estan etiquetados con el inicio de cada semana. De forma predeterminada, los datos remuestreados se etiquetan con el limite derecho para las frecuencia mensuales, trimestrales y anuales, y con el limite izquierdo para todas las demas frecuencias. Este comportamiento y otras opciones se pueden ajustar utilizando los parmetros enumerados en la documentacién de resampled). Ahora se exploraran las series temporales mensuales trazando el consumo de electricidad corno un diagrama de linea, y la produccién de energia edlica y solar juntas como un grafico de area apilada. figeeje © r eje_plot (oped _mensual ( ‘Consumption’ ], color "bla + ,Label="consumo') reneval|['Wind", Fea (axese, Linewidth=9) al Mensual (Wh) 40000 2 & soon 3 & 2 zoo 3 é p00) — Conair mE Wnt ar ° - a pt i es Date En esta escala de tiempo mensual, se observa claramente la estacionalidad anual en cada serie, y también es evidente que el consumo de electricidad se ha mantenido bastante estable a lo largo del tiempo, mientras que la produccién de energia edlica ha crecido constantemente, con la suma de energia edlica y solar (Wind+Solar) que comprende una parte cada vez mayor de la electricidad consumida. Haciendo un remuestreo a la frecuencia anual y calculando la relacién de la produccién de energia eélica y energia solar (WindSolar) con consumo (Consumption) para cada afio se profundizar4 en este tema. 1. | 59> epsd_anual = opsd_dia{columnas] .resample ("A") -sum(nin_coun 2. >> opsd_anual = opsd_anual.set_index epsd_anua!.index.year) 3. >> opsd_anual.index.nane="Anot 4. 55> opsd_anual (*Wind#Solar/Consumo'] = opsd_anuall[*Wing+Solar*] /- opsd_anual (*Consumption') 5. >>> epsd_anual.tail (4) 6 consumption Wing Solar wind-Solar Wind‘Solar/Consumo 8. 2014 S04i64.92100 $1107.672 32498.307 _89570.502 0.165368 9. 2018 505264.56300 77468.994 24907.138 112376.132 0.222410 10. 201€ 505927.35400 77008.126 34562.824 111570.950 0.220528 11. 2017 504736.36939 102667.365 38882.643 138550.008 9.274500 Finalmente, se trazaré la carga de la produccién de energla edlica y solar (Wind+Solar) del consumo anual de electricidad en un grafico de barras. 4 £1 grAtico comlenza en 2012, ya que antes de 2012 no # habia produceién de energia solar e3e = opsd anual. loc[2012:, 'Wind+Solar/Consune") .plot-bar () eje.set_ylabel (*Fraceién') e}e-set_ylim(0, 0.5) eje-set_title(*Carga de Consumo Anual Total Wind+Solar") (Carga de Consumo Anual Total Wind+Solar 05 04 03 a2 . U U Ll 00 ® R & & ® R Bo El cédigo final de los graficos de esta parte es: ler y 2do Grafico de Remuestreo 1. import pandas as pnd 2, Amport matplotlib-pyplot as spit 3. Amport seaborn as sbn . 5. sbn.set (re-(*Figure.figsize': (10, 5)}} 6 5. opsd_dia = prd.read_cev(‘opsd germany daily.cey', index _col=0, parse_dates: 8. 9. colunnas = [*Consumption', "Wind", ‘Solar', ‘WindtSolar"] 10. nedi_oped semanal ~ opsd dla[colunnas) .resample("H') mean () LL. opsd_sensual = opsd_dia{colurnas] .resample (*M") .sun{min_count=28) a. 13. # Ler Gratice 1M. nici, final = *2025-06", 2015-12" 15. figseje = apit-subpiets() 16. eje.piot (opsd_dia.lec{inicio: final, ‘Solar'],marker-'.', Linestyle-'-', linewidth-0.5,label="Diario'} 17. eje.plot imedia_opsd_semanal loc inicio: final, 'Solar'),marker='o" ,narkersize-5, label="senanal") 18. e}e-set_ylabel (*Produeccién Solar (GWh)") 19. eje-lesendt) 20 21. 4 2de Gratico 22. figseje = apit.subpiots () 23. e}e-plot (opsd_nensual [ ‘Consumption’ }, color-"black’ , label-'Consuno"} 24. opsd_menaual ([ Wind", ‘Solar')].plot.area(axvele, 1inewidth~0) 25. eja-legend( 26. eje-set_ylabel(*Total Mensual (GWh)") 3er Grafico de Remuestreo 1. import pandas as pnd 2. amport matplotiib.pyplot as spit 3. Amport soabors as shn 7 5. abn.set (reu{*#igure.figsize': (10, 5)}} 6. 7. opsd dia = pnd.read_csv("opsd germany daily.csv", index col=0, parse dates=Teue) 8. 9. 4 Ser Gratice 10. opsd_anual = opsd_diafcolunnas] .resample(*A") «sum (nin_count=360) i. i_anué Andex (opsd_anual.index.year) 13. opsd_anual ['Wind+Soiar/Co Mu, 1B. 1, 18, Ventanas Deslizantes mo") = opsd_anual ['Wind+Solar'] / opsd_anual{*Consumption* @ = oped_anual1oc jevset_yLin (9,0 20128, "Wind folar/Consume') .plot-bar() Las operaciones de ventanas deslizantes son otra transformacién importante para los datos de series temporales. De manera similar al submuestreo, las ventanas deslizantes dividen los datos en ventanas de tiempo y los datos de cada ventana se agregan con una funcién como mean(), median(), sumQ, entre otras. Sin embargo, a diferencia del submuestreo, donde los intervalos de tiempo no se superponen y la salida se encuentra a una frecuencia mas baja que la entrada, las ventanas deslizantes se superponen y “deslizan” a la misma frecuencia que los datos, por lo que las series temporales transformadas tienen la misma frecuencia que las series temporales originales. De forma predeterminada, todos los datos dentro de una ventana tienen la misma ponderacién en la sumatoria, pero esto se puede cambiar especificando tipos de ventana como Gaussiana, triangular y otras. Nos quedaremos con la ventana de ponderacién estandar aqui. Con el método rollingd se calcula la media deslizante de 7 dias de datos diarios. Usando el argumento center=True, se etiqueta cada ventana en su punto medio, por lo que las ventanas deslizantes seran: 2006-01-01 a 2006-01-07 - etiquetado como 2006-01-04 2006-01-02 a 2006-01-08 - etiquetado como 2006-01-05 2006-01-03 a 2006-01-09 - etiquetado como 2006-01-06 y asi sucesivamente, 1, 55> opsd_7d = oped dialcolumas].rolling(, center=Mewe) mean () 2. >>> opsd_Td.hea 3 Consumption Wind Solar windtSolar 5 Naw NaN Nay Naw 6 Naw NaN NaN Naw 2381.3001, Para visualizar las diferencias entre la media deslizante y el remuestreo, se actualiza el grafico anterior de la produccién de energia solar de junio a diciembre de 2015 para incluir la media deslizante de 7 dias junto con las series de tiempo remuestreadas medias semanales y los datos diarios originales. Amport pendas as pnd import matplotlib.pyplot as Amport seaborn as sha n set (re=( "figure. figsize': (10, 93) d.read_eav{ ¢_dates~True} 8. | opsd 7d = oped diafcolu 2015-12" 11, fig, eye = mplt. subplots () 12. opsd_dia.1 13 e.plot (media Inarker cio: final, ‘Solar’ nestyle= inicio: final, ‘Sol Mi. ese.pi (oped "Lymark nestyle='-', Linewidth0.5, label="Media 15, eje-set_ylabel ("Pro 16. edeslegendt i6n selaz (Gh) ") Dario Semanal Neda Desizante de 7 Das ao ° 21506-1507 NSB MISO NI IOwISYIS2 ate oF Se puede ver que los puntos de datos en la serie temporal de la media deslizante tienen el mismo espacio que los datos diarios, pero la curva es mas suave porque se ha promediado una mayor variabilidad de frecuencia. En las series temporales de media deslizante, los picos y valles tienden a alinearse estrechamente con los picos y valles de las series temporales diarias. En contraste, los picos y valles en las series de tiempo remuestreadas sermanalmente se alinean menos estrechamente con las series temporales diarias, ya que las series remuestreadas tienen una granularidad més gruesa. Tendencias Los datos de series temporales a menudo muestran una variabilidad lenta y gradual, ademés de una variabilidad de frecuencia més alta, como la estacionalidad y el ruido. Una forma facil de visualizar estas tendencias es con medias deslizantes en diferentes escalas de tiempo. Una media deslizante tiende a suavizar una serie temporal promediando las variaciones en frecuencias mucho mas altas que el tamajio de la ventana y promediando cualquier estacionalidad en una escala de tiempo igual al tamafio de la ventana. Esto permite explorar variaciones de baja frecuencia en los datos. Dado que la serie temporal que esté siendo utilizada tiene estacionalidad semanal y anual, se veran las medias deslizantes en esas dos escalas de tiempo. Ya se han calculado las medias deslizantes de 7 dias, por lo que ahora se calculara la media deslizante de 365 dias de los datos de OPSD. 1. 4 £1 argurente min period 60 toma en cuenta las faltantes en las medidas de energia solar 4. | opad_365d = opad_dia(columnas] .rolling (window=36S, centere®rue,min_periods=360) .mean() El grafico de esto serfa: 1 Amport pandas ae pnd 2) | dmport matplotiib-pyplot as spit 3. | import seaborn as sin ‘ 5) shn.set (ro=(*¢igure.tigsize' (10, $))) ‘ 7. psd dia = pnd.read_cev (‘oped germany daily.cev', index parse cate 8. | oped_a6sd ~ opsa_dialcolunnas] 2011109 windowe365,center~Bave, nin pefiods-260) sean () 9. Spadi?d = oped ia[columnas] ,rolling(?, center=Beve) smeant) 10. 11) fig, oe = mple.eumplote( 12. eje.plot(opsd_dia['Consumption'], marker='.', markersize=2, color='0.6", 13, Linestyles"Nose', label="Diario") LL eje.pivtloped73{"Consumption'], Zinewidth-2, Label "Wadia destizante seranai") 15. je.pt0t (oped 36Sa[‘cansunption*], coloe='0,2%, Iinewlat3, 16. label="Tendencia (Media deslizante anual) ") 17) jertegendt 18, aje.set_slabel "ano"? 19, Sjersetaylabel (eonsueo. (6m) *) 20. ejerset_title("Tendencias en el Consuno Electrico") “Tendencies en el Consumo Electico 1800 g 1400 2 2 3 ow0 8 ‘000 ‘ aa . — Media destizante sermanal — Tene (eda cesta nay ovo 00 00 aro pre aia aie are ro Se puede notar que la media deslizante de 7 dias ha suavizado toda la estacionalidad semana, al tiempo que conserva la estacionalidad anual. La media deslizante de 7 dias revela que, si bien el consumo de electricidad suele ser mayor en invierno y en verano, hay una disminucién dramatica durante algunas semanas cada invierno a fines de diciembre y principios de enero, durante las vacaciones. Si se observan las series temporales de media deslizante de 365 dias, es notable que la tendencia a largo plazo en el consumo de electricidad es bastante plana, con un par de perfodos de consumo anormalmente bajos entre 2009 y 2012-2013. Se observarn las tendencias en la produccién eélica y solar. 1.) figseje= eplt.subpiots() 2. for i am [‘Wind', 'Solar', ‘WindrSolar']: 3. eje.plot (opsd_365d[i}, label=i) eje-set_ylim(0,500) eje-leggnaty ejerset_ylabel (*Produccién (GH) ") eje-set_title(*Tendencias en ta Produccién de electricidad') Tendencas en la Produccion ge electicgad oo — Wea = soar — Vind: Solar 0 3 00 5 3 3 a0 ‘0 Se ° pi mt mis mts Se puede ver una pequefia tendencia creciente en la produccién de energfa solar y una gran tendencia creciente en la produccién de energfa eélica, a medida que Alemania continda expandiendo su capacidad en ambos sectores. EI cédigo del apartado de Tendencias seria: 1. import pandas as pnd 2. Amport matplotlib.eyplot ae nplt 3. import seaborn as sha 1 5. gbn.set (ren{'Figure.figsize': (10, 5)}} 6. 7. opsd_dia = pnd.read_csv(*opsd_germany_daily. index_col: 8. opsd_365d = opsd_dialcolumnas] roiling (window365, center~Teue,min_periods~360) .mean{) 9. opsd_?d ~ oped dia(columnas]rolling(3, center-feue) mean () ao. AL. Ler Grasice 12. fig, eje = mplt-subplota() 13. eje-plot (opsd dial Consumption’), marker='.', markersize=2, color=0.6", 14. Linestyle="Nene", Label="Diario") 15. eje.plot(opsd_7a{‘Consumption'], Linewidth-2, label="Media deslizante senanal') 16. eje.plot (opsd_365a(‘Consumption"], color='0.2", Linewidth=3, 17. label="Tendencia (Media desitzante anval) ") 18. ede.legend() 19. aje.set_xlabel ('Ato") 20. tylabel (‘Consume (GH) ") 21. eje-set_title(*Tendencias en el Consuno Electrico’) 22. 23. 4 2do Gratice 24. figeeje= mplt.subplots() 25. for i in ["Wind", "Solar', "Wind+Setar’ 26 eje-plot (opsd_365d/i}, label=i) 27 eje-set_ylim(@, 500) 28. eje- legend) 29. eje-set_ylabel ("Produccisn (Wh) ") 20 eje-set title (*Tendencias en la Produccién de electricidad')

You might also like