preloader

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.

python
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'
python
sklearn.model_selection.train_test_split()

regressor = sklearn.linear_model.LogisticRegression()
regressor = LogisticRegression()
python
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:

python
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

python
import pandas as pd
python
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í:

python
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

python
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.

python
productos = pd.Series(["Manzanas", "Cerezas", "Naranjas de zumo"])
productos
0            Manzanas
1             Cerezas
2    Naranjas de zumo
dtype: object
python
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:

python
frutas_df = pd.DataFrame({"Producto": productos,
             "Precio": precios})
frutas_df

ProductoPrecio
0Manzanas0.99
1Cerezas2.95
2Naranjas de zumo0.79
python
frutas_df.columns
Index(['Producto', 'Precio'], dtype='object')
python
frutas_df.index
RangeIndex(start=0, stop=3, step=1)
python
frutas_df.shape
(3, 2)
python
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:

python
pd.DataFrame({"Producto": ["Manzanas", "Cerezas", "Naranjas de zumo"],
             "Precio": [0.99, 2.95, 0.79]})

ProductoPrecio
0Manzanas0.99
1Cerezas2.95
2Naranjas de zumo0.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:

python
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:

python
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

Columna1Columna2Columna3Columna4Columna5Columna6
02020-09-2210.05.0Valor1Valor2
12020-09-2210.05.0Valor2Valor2
22020-09-2210.05.0Valor3Valor2
32020-09-2210.05.0Valor4Valor2
42020-09-2210.05.0Valor5Valor2
52020-09-2210.05.0Valor6Valor2
python
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:

python
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

python
# 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)
python
# 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

python
# 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.

comments powered by Disqus