pandas es una biblioteca de análisis de datos en Python que nos provee de las estructuras de datos y herramientas para realizar análisis de manera rápida. Se articula sobre la biblioteca NumPy y nos permite enfrentarnos a situaciones en las que tenemos que manejar datos reales que requieren seguir un proceso de carga, limpieza, filtrado, reduccióń y análisis.
En esta clase veremos como cargar y guardar datos, las características de las pricipales estructuras de pandas y las aplicaremos a algunos problemas.
In [11]:
# Importamos pandas
%matplotlib inline
import pandas as pd
import matplotlib.pyplot as plt
Trabajaremos sobre un fichero de datos metereológicos de la Consejeria Agricultura Pesca y Desarrollo Rural Andalucía.
In [12]:
# Vemos qué pinta tiene el fichero
!head ./tabernas_meteo_data.txt
Vemos que los datos no están en formato CSV, aunque sí tienen algo de estructura. Si intentamos cargarlos con pandas no tendremos mucho éxito:
In [13]:
# Tratamos de cargarlo en pandas
pd.read_csv("./tabernas_meteo_data.txt").head(5)
Out[13]:
Tenemos que hacer los siguientes cambios:
In [14]:
data = pd.read_csv(
"./tabernas_meteo_data.txt",
delim_whitespace=True, # delimitado por espacios en blanco
usecols=(0, 2, 3, 4, 5), # columnas que queremos usar
skiprows=2, # saltar las dos primeras líneas
names=['DATE', 'TMAX', 'TMIN', 'TMED', 'PRECIP'],
parse_dates=['DATE'],
# date_parser=lambda x: pd.datetime.strptime(x, '%d-%m-%y'), # Parseo manual
dayfirst=True, # ¡Importante
index_col=["DATE"] # Si queremos indexar por fechas
)
# Ordenando de más antigua a más moderna
data.sort_index(inplace=True)
# Mostrando sólo las primeras o las últimas líneas
data.head()
Out[14]:
In [15]:
# Comprobamos los tipos de datos de la columnas
data.dtypes
Out[15]:
Las fechas también se pueden parsear de manera manual con el argumento:
date_parser=lambda x: pd.datetime.strptime(x, '%d-%m-%y'), # Parseo manual
In [16]:
# Pedomos información general del dataset
data.info()
In [17]:
# Descripción estadística
data.describe()
Out[17]:
In [18]:
# Una vez convertido en un objeto fecha se pueden obtener cosas como:
data.index.dayofweek
Out[18]:
Tenemos dos formas de acceder a las columnas: por nombre o por atributo (si no contienen espacios ni caracteres especiales).
In [19]:
# Accediendo como clave
data['TMAX'].head()
Out[19]:
In [20]:
# Accediendo como atributo
data.TMIN.head()
Out[20]:
In [21]:
# Accediendo a varias columnas a la vez
data[['TMAX', 'TMIN']].head()
Out[21]:
In [22]:
# Modificando valores de columnas
data[['TMAX', 'TMIN']] / 10
Out[22]:
In [23]:
# Aplicando una función a una columna entera (ej. media numpy)
import numpy as np
np.mean(data.TMAX)
Out[23]:
In [24]:
# Calculando la media con pandas
data.TMAX.mean()
Out[24]:
Para acceder a las filas tenemos dos métodos: .loc
(basado en etiquetas), .iloc
(basado en posiciones enteras) y .ix
(que combina ambos).
In [25]:
# Accediendo a una fila por índice
data.iloc[1]
Out[25]:
In [26]:
# Accediendo a una fila por etiqueta
data.loc["2016-09-02"]
Out[26]:
Puedo incluso hacer secciones basadas en fechas:
In [27]:
data.loc["2016-12-01":]
Out[27]:
También puedo indexar utilizando arrays de valores booleanos, por ejemplo procedentes de la comprobación de una condición:
In [28]:
# Búsqueda de valores nulos
data.loc[data.TMIN.isnull()]
Out[28]:
Podemos agrupar nuestros datos utilizando groupby
:
In [29]:
# Agruparemos por año y día: creemos dos columnas nuevas
data['year'] = data.index.year
data['month'] = data.index.month
In [30]:
# Creamos la agrupación
monthly = data.groupby(by=['year', 'month'])
In [31]:
# Podemos ver los grupos que se han creado
monthly.groups.keys()
Out[31]:
In [32]:
# Accedemos a un grupo
monthly.get_group((2016,3)).head()
Out[32]:
In [33]:
# O hacemos una agregación de los datos:
monthly_mean = monthly.mean()
monthly_mean.head(24)
Out[33]:
Y podemos reorganizar los datos utilizando pivot tables:
In [34]:
# Dejar los años como índices y ver la media mensual en cada columna
monthly_mean.reset_index().pivot(index='year', columns='month')
Out[34]:
Por último, pandas proporciona métodos para calcular magnitudes como medias móviles usando el método rolling
:
In [35]:
# Calcular la media de la columna TMAX
monthly.TMAX.mean().head(15)
Out[35]:
In [36]:
# Media trimensual centrada
monthly_mean.TMAX.rolling(3, center=True).mean().head(15)
Out[36]:
In [37]:
# Pintar la temperatura máx, min, med
data.plot(y=["TMAX", "TMIN", "TMED"])
plt.title('Temperaturas')
Out[37]:
In [38]:
data.loc[:, 'TMAX':'PRECIP'].plot.box()
Out[38]:
Pintando la temperatura máxima de las máximas, mínima de las mínimas, media de las medias para cada día del año de los años disponnibles
In [39]:
group_daily = data.groupby(['month', data.index.day])
daily_agg = group_daily.agg({'TMED': 'mean', 'TMAX': 'max', 'TMIN': 'min', 'PRECIP': 'mean'})
daily_agg.head()
Out[39]:
In [40]:
daily_agg.plot(y=['TMED', 'TMAX', 'TMIN'])
Out[40]:
In [41]:
# scatter_matrix
from pandas.tools.plotting import scatter_matrix
axes = scatter_matrix(data.loc[:, "TMAX":"TMED"])
In [43]:
# Esta celda da el estilo al notebook
from IPython.core.display import HTML
css_file = './css/aeropython.css'
HTML(open(css_file, "r").read())
Out[43]:
In [ ]: