Estructuras de datos y lectura de archivos
Índice de contenido
Carga de la librería pandas
Generalmente, para importar cualquier librería escribimos la palabra import seguida del nombre de la librería y, además, le ponemos un alias para después utilizarla con mayor comodidad.
En esta clase, importaremos pandas junto a la librería NumPy, que utilizaremos en ejemplos más abajo.
import numpy as np
import pandas as pd
import sklearn # Librería
from sklearn import linear_model # Módulo
from sklearn.linear_model import LogisticRegression # Clase
# from sklearn import * # MALA PRÁCTICA
---------------------------------------------------------------------------
ModuleNotFoundError Traceback (most recent call last)
<ipython-input-10-fc6464c74017> in <module>
1 import numpy as np
2 import pandas as pd
----> 3 import sklearn
ModuleNotFoundError: No module named 'sklearn'
sklearn.model_selection.train_test_split()
regressor = sklearn.linear_model.LogisticRegression()
regressor = LogisticRegression()
np.linspace(0, 2, 100)
array([0. , 0.02020202, 0.04040404, 0.06060606, 0.08080808,
0.1010101 , 0.12121212, 0.14141414, 0.16161616, 0.18181818,
0.2020202 , 0.22222222, 0.24242424, 0.26262626, 0.28282828,
0.3030303 , 0.32323232, 0.34343434, 0.36363636, 0.38383838,
0.4040404 , 0.42424242, 0.44444444, 0.46464646, 0.48484848,
0.50505051, 0.52525253, 0.54545455, 0.56565657, 0.58585859,
0.60606061, 0.62626263, 0.64646465, 0.66666667, 0.68686869,
0.70707071, 0.72727273, 0.74747475, 0.76767677, 0.78787879,
0.80808081, 0.82828283, 0.84848485, 0.86868687, 0.88888889,
0.90909091, 0.92929293, 0.94949495, 0.96969697, 0.98989899,
1.01010101, 1.03030303, 1.05050505, 1.07070707, 1.09090909,
1.11111111, 1.13131313, 1.15151515, 1.17171717, 1.19191919,
1.21212121, 1.23232323, 1.25252525, 1.27272727, 1.29292929,
1.31313131, 1.33333333, 1.35353535, 1.37373737, 1.39393939,
1.41414141, 1.43434343, 1.45454545, 1.47474747, 1.49494949,
1.51515152, 1.53535354, 1.55555556, 1.57575758, 1.5959596 ,
1.61616162, 1.63636364, 1.65656566, 1.67676768, 1.6969697 ,
1.71717172, 1.73737374, 1.75757576, 1.77777778, 1.7979798 ,
1.81818182, 1.83838384, 1.85858586, 1.87878788, 1.8989899 ,
1.91919192, 1.93939394, 1.95959596, 1.97979798, 2. ])
Estructuras de datos de pandas
Las estructuras de datos típicas de pandas son las Series y los DataFrames (en esta clase los escribiremos así, aunque es habitual encontrarlos escritos directamente como series y dataframes).
Series
Concepto
Un objeto de tipo Serie es una estructura unidimensional que contiene una secuencia de datos, es decir, es un objeto similar a una lista de valores. Además, también contiene una secuencia de etiquetas asociadas a los datos, que actúan como un índice. La forma general de crear una Serie es la siguiente:
pd.Series(data, index)
Donde:
- data puede ser una lista de valores, un diccionario de Python, un ndarray (matriz de NumPy), un valor escalar…
- index es una lista de etiquetas para el eje.
Veamos algunos ejemplos.
Ejemplos
Creación de una Serie a partir de una lista de valores
import pandas as pd
lista_valores = ["Manzanas", "Cerezas", "Naranjas de zumo"]
serie1 = pd.Series(data = lista_valores,
index = None)
serie1
0 Manzanas
1 Cerezas
2 Naranjas de zumo
dtype: object
En el ejemplo anterior, como no se ha especificado un índice concreto, pandas crea por defecto un índice con números enteros:
- El registro 0 es Manzanas
- El registro 1 es Cerezas
- El registro 2 es Naranjas de zumo
Si quieres especificar otro índice distinto, puedes hacerlo así:
pd.Series(data = lista_valores,
index = ["Fruta1", "Fruta2", "Fruta3"])
Fruta1 Manzanas
Fruta2 Cerezas
Fruta3 Naranjas de zumo
dtype: object
Creación de una Serie a partir de un diccionario
pd.Series(data = {
"valor1": 1,
"valor2": 2,
"valor3": 3
})
valor1 1
valor2 2
valor3 3
dtype: int64
DataFrames
Concepto
Un DataFrame es una estructura de datos de dos dimensiones: en esencia, es una tabla con filas y columnas, en la cual las columnas tienen un nombre y las filas tienen un índice.
Un DataFrame se puede crear a partir de diversos elementos:
- Un diccionario de ndarrays de 1 dimensión, listas, diccionarios o Series
- Un ndarray de 2 dimensiones
- Otro DataFrame
- Etc.
Veamos algunos ejemplos.
Ejemplos
Creación de un DataFrame a partir de un diccionario de Series
En el ejemplo a continuación, se crean dos Series que después se utilizan para construir un DataFrame.
productos = pd.Series(["Manzanas", "Cerezas", "Naranjas de zumo"])
productos
0 Manzanas
1 Cerezas
2 Naranjas de zumo
dtype: object
precios = pd.Series([0.99, 2.95, 0.79])
precios
0 0.99
1 2.95
2 0.79
dtype: float64
Una vez guardadas las dos Series en dos variables, podemos crear un DataFrame a partir de ellas. Para ello, utilizamos el constructor pd.DataFrame, que contiene un diccionario con el nombre que queremos que tengan las columnas como clave y las Series anteriores como valores:
frutas_df = pd.DataFrame({"Producto": productos,
"Precio": precios})
frutas_df
| Producto | Precio | |
|---|---|---|
| 0 | Manzanas | 0.99 |
| 1 | Cerezas | 2.95 |
| 2 | Naranjas de zumo | 0.79 |
frutas_df.columns
Index(['Producto', 'Precio'], dtype='object')
frutas_df.index
RangeIndex(start=0, stop=3, step=1)
frutas_df.shape
(3, 2)
frutas_df.values
array([['Manzanas', 0.99],
['Cerezas', 2.95],
['Naranjas de zumo', 0.79]], dtype=object)
En esencia, una Serie se puede considerar como una columna de un DataFrame.
Creación de un DataFrame a partir de un diccionario de listas
El mismo DataFrame del ejemplo anterior también se puede construir de manera muy simple mediante un diccionario que tiene como claves los nombres de las variables (que serán los nombres de las columnas) y como valores las listas que contienen los datos de cada variable:
pd.DataFrame({"Producto": ["Manzanas", "Cerezas", "Naranjas de zumo"],
"Precio": [0.99, 2.95, 0.79]})
| Producto | Precio | |
|---|---|---|
| 0 | Manzanas | 0.99 |
| 1 | Cerezas | 2.95 |
| 2 | Naranjas de zumo | 0.79 |
Como ves, un objeto de tipo DataFrame puede contener variables de todo tipo: int (números enteros), string (cadenas de texto), etc. Para comprobar los tipos de las variables de un DataFrame, se utiliza la siguiente propiedad:
frutas_df.dtypes
Producto object
Precio float64
dtype: object
Creación de un DataFrame a partir de un diccionario de múltiples estructuras
El siguiente ejemplo muestra cómo se construye un DataFrame mediante un diccionario con diversos tipos de variables:
df = pd.DataFrame({
"Columna1": pd.Timestamp("20200922"),
"Columna2": pd.Series(10, index=list(range(6)), dtype="float32"),
"Columna3": 5.,
"Columna4": pd.Categorical(["Valor1", "Valor2", "Valor3", "Valor4", "Valor5", "Valor6"]),
"Columna5": "Valor",
"Columna6": np.array([2]*6, dtype = "int32")
})
df
| Columna1 | Columna2 | Columna3 | Columna4 | Columna5 | Columna6 | |
|---|---|---|---|---|---|---|
| 0 | 2020-09-22 | 10.0 | 5.0 | Valor1 | Valor | 2 |
| 1 | 2020-09-22 | 10.0 | 5.0 | Valor2 | Valor | 2 |
| 2 | 2020-09-22 | 10.0 | 5.0 | Valor3 | Valor | 2 |
| 3 | 2020-09-22 | 10.0 | 5.0 | Valor4 | Valor | 2 |
| 4 | 2020-09-22 | 10.0 | 5.0 | Valor5 | Valor | 2 |
| 5 | 2020-09-22 | 10.0 | 5.0 | Valor6 | Valor | 2 |
df.dtypes
Columna1 datetime64[ns]
Columna2 float32
Columna3 float64
Columna4 category
Columna5 object
Columna6 int32
dtype: object
Como puedes ver, hemos creado cada columna a partir de una estructura diferente:
- Columna 1: un valor constante de tipo Timestamp, que se repetirá tantas veces como valores tenga la columna más larga del DataFrame.
- Columna 2: una Serie formada por el valor constante 10 (de tipo float32) repetido 6 veces, ya que queremos que el DataFrame tenga 6 filas.
- Columna 3: un valor constante de tipo float64 (lo indicamos al poner un punto a la derecha del número), que se repetirá tantas veces como valores tenga la columna más larga del DataFrame.
- Columna 4: una variable categórica con 6 categorías (queremos que el DataFrame tenga 6 filas).
- Columna 5: un valor constante de tipo string, que se repetirá tantas veces como valores tenga la columna más larga del DataFrame.
- Columna 6: un array de numpy formado por el valor 2 (de tipo int32) repetido 6 veces.
Además, hemos añadido un índice manualmente.
Comprobemos los tipos de las columnas del DataFrame que acabamos de crear:
Lectura de datos de archivos
Lo normal no es crear los datos desde cero como en los ejemplos anteriores. Lo más común es tener datos ya existentes, como por ejemplo en archivos en un formato concreto (.csv, .tsv, .xlsx, .json, etc.) o en tablas SQL, aunque las opciones son muy numerosas. En cualquier caso, el objetivo es el mismo: leer esos datos y cargarlos en un DataFrame para poder procesarlos. Para ello, pandas cuenta con diversas funciones que permiten cubrir prácticamente cualquier caso de uso.
Lectura de archivos csv
Un archivo CSV es, en esencia, una tabla de valores que están separados unos de otros mediante comas (aunque también pueden estar separados por otro tipo de delimitadores, como por ejemplo puntos y comas o el caracter “invisible” que surge cuando se presiona la tecla tab). Al abrir un archivo de este tipo, habitualmente nos encontraremos algo similar a lo siguiente:
Producto, Precio,
Manzanas, 0.99,
Cerezas, 2.95,
Naranjas de zumo, 0.79,
Parámetros principales
La función de pandas que se encarga de leer archivos CSV es pd.read_csv(). Aunque permite especificar un número enorme de parámetros, aquí mostraremos el uso de esta función incluyendo solo algunos de los más relevantes:
- filepath_or_buffer es la ruta donde se encuentra el archivo que queremos leer. Debe ir entre comillas (tiene que ser un string).
- sep es el caracter por el cual los datos están separados unos de otros. Por defecto, pandas considera una coma, pero puedes encontrar archivos csv en los que el caracter es de otro tipo y, para leerlo correctamente, necesitarás especificarlo mediante este parámetro.
- header permite especificar la fila del archivo csv que se usará para generar los nombres de las columnas. Puede ser:
- “infer”, que es el que viene por defecto y equivale a header=0, es decir, los nombres de columna se deducen de la primera línea del archivo.
- Un número entero, para indicar el índice de la fila que se quiere utilizar.
- Una lista de enteros, para generar un multi-índice de columnas.
- names es una lista con los nombres que se les quiere dar a las columnas. Si el archivo ya tiene un encabezaso y se quiere sobreescribir con la lista de nombres manualmente, se debe pasar el argumento header=0 para indicarlo. No permite nombres duplicados.
- skiprows son las filas a ignorar, es decir, las filas del archivo que no queremos leer ni incorporar a un DataFrame. Puede especificarse mediante una lista (con los números de las líneas a ignorar, que pueden no ser consecutivas) o mediante un número entero (para ignorar las primeras líneas).
- nrows es el número de filas a leer. Es útil para archivos muy grandes en los que queremos limitar el número de filas que se cargan en un DataFrame.
- parse_dates puede ser (entre otras posibles configuraciones que aquí no veremos):
- “True”, si queremos que pandas intente cargar el índice como fechas.
- “False”, si queremos que pandas no trate de interpretar nada como una fecha.
- Una lista de enteros o nombres, si queremos leer solo ciertas columnas como fechas.
Existen muchísimos otros parámetros de la función read_csv() que pueden utilizarse para generar un DataFrame a partir de un archivo csv, ajustándose a nuestras necesidades de la mejor forma posible.
Ejemplos
# Ejemplo de carga de un csv con delimitador ","
file_path =
time_cols =
pd.read_csv(filepath_or_buffer=,
sep=,
header=,
names=,
skiprows=,
nrows=,
parse_dates=time_cols)
# Ejemplo de carga de un csv con delimitador " "
file_path =
time_cols = []
pd.read_csv(filepath_or_buffer=,
sep=,
skiprows=,
nrows=,
parse_dates=time_cols)
Lectura de archivos xlsx
Parámetros principales
Para cargar los datos de archivos excel en DataFrames, pandas cuenta con la función pd.read_excel(). En realidad, esta función no solo está preparada para leer archivos en formato xlsx, sino también en xls, xlsm, xlsb, y odf. Además, cuenta con una opción para cargar una sola hoja del archivo excel o una lista de hojas. De la misma forma que para el caso de los archivos csv, aquí consideraremos solo algunos de los muchos parámetros de esta función:
- io es la ruta donde se encuentra el archivo que queremos leer. Debe ir entre comillas (tiene que ser un string).
- sheet_name permite especificar las hojas que se quieren cargar:
- Por defecto es 0 e indica que solo se quiere leer la primera hoja.
- Si es 1, indica que se quiere leer la segunda hoja.
- Si es un string, carga la hoja con el nombre de ese string. Por ejemplo, indicando “Sheet1” se cargará la hoja de nombre “Sheet1”.
- Si es una lista, carga las hojas especificadas en la lista. Por ejemplo, la lista [0, 1, “Sheet4”] hará que la función cargue la primera hoja, la segunda hoja y la hoja que tenga el nombre “Sheet4”.
- Si es None, cargará todas las hojas.
- header permite especificar la fila del archivo excel que se usará para generar los nombres de las columnas. Puede ser:
- Un número entero, para indicar el índice de la fila que se quiere utilizar. Por defecto es 0, por lo que usa la primera fila del archivo como etiquetas de las columnas.
- Una lista de enteros, para generar un multi-índice.
- Si es None, no utiliza ningún encabezado.
- skiprows son las filas a ignorar, es decir, las filas del archivo que no queremos leer ni incorporar a un DataFrame. Puede especificarse mediante una lista (con los números de las líneas a ignorar, que pueden no ser consecutivas) o mediante un número entero (para ignorar las primeras líneas).
- nrows es el número de filas a leer. Es útil para archivos muy grandes en los que queremos limitar el número de filas que se cargan en un DataFrame.
- parse_dates puede ser (entre otras posibles configuraciones que aquí no veremos):
- “True”, si queremos que pandas intente cargar el índice como fechas.
- “False”, si queremos que pandas no trate de interpretar nada como una fecha.
- Una lista de enteros o nombres, si queremos leer solo ciertas columnas como fechas.
Existen muchísimos otros parámetros de la función read_excel() que pueden utilizarse para generar un DataFrame a partir de un archivo en formato xlsx, xls, xlsm, xlsb, y odf.
Ejemplos
# Ejemplo de carga de un archivo xlsx
file_path =
time_cols = []
pd.read_excel(io=,
sheet_name=,
header=,
skiprows=,
nrows=,
parse_dates=time_cols)
Lectura de archivos con otros formatos
Pandas cuenta con un gran número de funciones similares a read_csv() y read_excel(), que nos permiten leer datos de prácticamente cualquier procedencia:
- pd.read_sql()
- pd.read_json
- pd.read_html()
- Etc.
El uso de todas estas funciones es muy parecido: únicamente requiere consultar la documentación oficial de pandas para seleccionar los parámetros que necesitemos incluir.
