Introducción a Pandas
Pandas es un API para el análisis de datos orientados en columnas. Es perfecto para analizar y manipular datos y muchos frameworks de ML soportan estructuras de datos pandas como entradas. En este post vamos a mencionar conceptos basicos y contretos, ya que una buena introduccion al Panda API ocuparía varias pagina. La información completa se referencia en panda_docs_site
Conceptos Basicos
Para importar el panda API e imprimir su version de API ejecuta:
from __future__ import print_function import pandas as pd pd.__version__ >u'0.22.0'
Las estructuras de datos basicas implementan dos clases:
- DataFrame, que se asemejan a una tabla de datos relacional con filas y columnas nombradas
- Series, columnas simples. Un DataFrame contien uno o mas Series y un nombre para cada Series
Los data frames son una abstracción utilizada para manipular datos similarmente a los existentes en Spark y R.
Ejemplo de creación de Series
pd.Series(['San Francisco', 'San Jose', 'Sacramento']) 0 San Francisco 1 San Jose 2 Sacramento dtype: object
Un DataFrame puede ser creado pasando un mapa en el cual tengamos un nombre string para la columna y su Series. Si las Series no son de la misma longitud, los valores que faltan se completan con valores NA/NaN.
city_names = pd.Series(['San Francisco', 'San Jose', 'Sacramento']) population = pd.Series([852469, 1015785, 485199]) pd.DataFrame({ 'City name': city_names, 'Population': population }) > City name Population 0 San Francisco 852469 1 San Jose 1015785 2 Sacramento 485199
Aunque nos sirve de ejemplo, la mayoría de las veces cargaremos un fichero entero en un DataFrame. El siguiente código carga un fichero con los datos de las casas de Carolina.
california_housing_dataframe = pd.read_csv("https://download.mlcc.google.com/mledu-datasets/california_housing_train.csv", sep=",") california_housing_dataframe.describe()
Usando DataFrame.describe() muestra estadistica interesante sobre el DataFrame. Otra función muy usada es DataFrame.head() que muestra unos primeros registros.
california_housing_dataframe.head()
Acceso a Datos
Se puede acceder a los datos de un DataFrame usando las operaciones familiarizadas de Python dict/list
cities = pd.DataFrame({ 'City name': city_names, 'Population': population }) print(type(cities['City name'])) cities['City name'] > <class 'pandas.core.series.Series'> 0 San Francisco 1 San Jose 2 Sacramento Name: City name, dtype: object
print(type(cities['City name'][1])) cities['City name'][1] > <type 'str'> 'San Jose'
print(type(cities[0:2])) cities[0:2] > <class 'pandas.core.frame.DataFrame'> City name Population 0 San Francisco 852469 1 San Jose 1015785
Manipulating Data
Puedes aplicar las operaciones aritméticas básicas de Python a Series
population / 1000. > 0 852.469 1 1015.785 2 485.199 dtype: float64
NumPy es una popular herramienta para la computación cientifica, cuyas funciones pueden usar como argumentos panda Series.
import numpy as np np.log(population) > 0 13.655892 1 13.831172 2 13.092314 dtype: float64
Si se necesitan trasformaciones más complejas, puedes utilizar Series.apply; al igual que la función map de Python. Series.apply acepta como argumento la función lambda que se aplica a cada valor.
population.apply(lambda val: val > 1000000) > 0 False 1 True 2 False dtype: bool
Modificar DataFrames es también directo.
cities['Area square miles'] = pd.Series([46.87, 176.53, 97.92]) cities['Population density'] = cities['Population'] / cities['Area square miles'] cities > City name Population Area square miles Population density 0 San Francisco 852469 46.87 18187.945381 1 San Jose 1015785 176.53 5754.177760 2 Sacramento 485199 97.92 4955.055147
Si queremos combinar dos operaciones para modificar el DataFrame en función de condiciones aplicadas a otras Series. En el ejemplo siguiente vemos como hacerlo:
cities['Is wide and has saint name'] = (cities['Area square miles'] > 50) & cities['City name'].apply(lambda name: name.startswith('San')) cities > City name Population Area square miles Population density Is wide and has saint name 0 San Francisco 852469 46.87 18187.945381 False 1 San Jose 1015785 176.53 5754.177760 True 2 Sacramento 485199 97.92 4955.055147 False
Indicés
Tanto los objetos Series como los DataFrames definen una propiedad llamada index que asigna un identificador a cada elemento de la Series o a cada fila del DataFrame.
Por defectos, en construcción, pandas asigna indices que reflejan el orden de los datos fuente. Una vez creado, los valores de los indices son estable, lo que quiere decir que no cambian cando los datos sean reordenados.
city_names.index > RangeIndex(start=0, stop=3, step=1)
Utiliza DataFrame.reindex para reordenar manualmente las filas. El siguiente ejemplo tiene el mismo efecto que ordenar por nombre de ciudad.
cities.reindex([2, 0, 1]) > City name Population Area square miles Population density Is wide and has saint name 2 Sacramento 485199 97.92 4955.055147 False 0 San Francisco 852469 46.87 18187.945381 False 1 San Jose 1015785 176.53 5754.177760 True
La reindexación es una estupenda manera de mezclar un DataFrame. A continuación, tomamos el indice, que es como una matriz y lo pasamos a la función random.permutacion de NumPy que barajea los valores en su lugar.
cities.reindex(np.random.permutation(cities.index)) > City name Population Area square miles Population density Is wide and has saint name 1 San Jose 1015785 176.53 5754.177760 True 2 Sacramento 485199 97.92 4955.055147 False 0 San Francisco 852469 46.87 18187.945381 False
Además de esto el método reindex permite indexar valores que no están en los valores del DataFrame original.
cities.reindex([0, 4, 5, 2]) > City name Population Area square miles Population density Is wide and has saint name 0 San Francisco 852469.0 46.87 18187.945381 False 4 NaN NaN NaN NaN NaN 5 NaN NaN NaN NaN NaN 2 Sacramento 485199.0 97.92 4955.055147 False Esto es posible porque los indices a menudo son cadenas obtenidas de los datos reales. Los indices "faltantes" usan una lista externa ya que no se procupan de ser una entrada válida.
0 comentarios