Saltar a contenido

Trabajar con datos en Python

Si eres un científico trabajas con datos. Citando a Mythbusters, the only difference between screwing around and science is writing it down. Existen millones de librerías para leer diferentes tipos de datos, desde imágenes y ficheros de audio a formatos súper específicos como discretizados de superficies y volúmenes (meshes).

Índice

  1. numpy
  2. pandas
  3. csv
  4. JSON

numpy

numpy es un paquete de Python para manejar vectores o arrays en una o más dimensiones. Es una de las librerías más útiles y que más he usado.

Múltiples columnas, separados por espacios o tabuladores

El caso más sencillo es que el fichero contenga datos numéricos en forma de una matriz NxM, donde N es el número de filas y M es el número de columnas. Si los datos están separados por espacios o tabuladores, numpy es la forma más fácil de hacerlo:

import numpy as np

data = np.loadtxt("data01.dat")

Donde data01.dat es el fichero de datos. data es un objeto que contiene los datos como si fuera una matriz. data.shape proporciona las dimensiones del array, en este caso 2D.

col_data = data[:,0]
es la forma de acceder a datos por columnas, en este caso la primera columna. numpy permite hacer operaciones entre columnas, por ejemplo:

sum_cols = data[:,0] + data[:,1]

Ignorar líneas

Muchos ficheros contienen comentarios o el nombre de las columnas. numpy no tiene la capacidad de trabajar con los nombres de las columnas, con lo que lo apropiado es ignorar esas líneas:

import numpy as np

data = np.loadtxt("data02.dat", skiprows=3)
ignora las primeras tres líneas del fichero.

Por defecto, numpy ignora las líneas que comienzan con la almohadilla (#)

Valores separados por comas

Si los valores están separados por comas, numpy permite especificar el delimitador de los campos en el fichero:

import numpy as np

data = np.loadtxt("data03.dat", delimiter=',')
Esto es útil para leer ficheros con datos en formato CSV, como por ejemplo al exportar hojas de excel.

Limitaciones

numpy.loadtxt tiene una serie de limitaciones:

  • Un array en numpy no puede contener más de un tipo de variable. Por ejemplo, si la columna primera son enteros y el resto floats, numpy importa todo como float. Es posible especificar el tipo de dato usando el modificador dtype.

  • numpy no puede asociar nombres de columnas a los datos.

Para eso es necesario usar pandas.

pandas

pandas es un paquete de Python que extiende la capacidad de numpy para trabajar con dataframes. Los tres motivos principales son para analizar ficheros donde las columnas mezclan diferentes tipos de variables (strings, ints, floats, etc), cuando queremos preservar los nombres de las columnas, y cuando cada fila tiene su propio nombre o índice.

pandas tiene varias particularidades:

  • Tiende a asumir que la primera columna de un fichero contiene un índice. Esto puede ser más común cuando trabajas con dataframes, pero es muy poco común en ficheros con datos numéricos.
  • Está diseñado para acceder a las columnas por nombre, hay forma de hacerlo por número pero no es evidente.

Datos separados por comas con títulos en las columnas

Supongamos el fichero data01.dat:

X,Y
0.0, 0.0
1.0, 2.0
2.0, 3.0

pandas permite acceder a los datos por columnas:

import pandas as pd
data = pd.read_csv("data01.dat")
print(data['X'])
Sin embargo, si intentamos usar slices para acceder a la primera columna como en numpy usando:
print(data[:,0])
obtenemos un error. De hecho, el resultado de data['X'] es un objeto de tipo Series.

Si consideramos ahora el siguiente fichero:

Ciudad,Ranking
Sevilla,1
Chicago,2
Madrid,3
y corremos el siguiente código:
import pandas as pd

data = pd.read_csv("data02.dat")
print(data['Ciudad'])
print(data['Ranking'])
El resultado es:
0    Sevilla
1    Chicago
2     Madrid
Name: Ciudad, dtype: object
0    1
1    2
2    3
Name: Ranking, dtype: int64
La columna 'Ranking' es de tipo int64, mientras que 'Ciudad' es de tipo object, que representa un objecto genérico en Python. Si modificamos el fichero de manera que el Ranking de Sevilla es 1.0:
Ciudad,Ranking
Sevilla,1.0
Chicago,2
Madrid,3
el resultado es que la columna 'Ranking' es ahora de tipo float64.

Convertir el formato a un numpy array es trivial:

import pandas as pd

data = pd.read_csv("data03.dat")
data_np = data["Ranking"].to_numpy()
print(data_np, type(data_np))
Resulta en:
[1. 2. 3.] <class 'numpy.ndarray'>

Ficheros csv

Python viene con un módulo para leer ficheros separados por comas. Es una alternativa a tener que instalar pandas, pero requiere un poco más de esfuerzo. Un ejemplo de código para leer un fichero csv es el siguiente:

import csv
with open('fichero.csv', 'r') as fp:
    reader = csv.reader(fp)
    data = [row for row in reader]
La interpretación es la siguiente: csv.reader crea un iterator que permite leer el fichero línea a línea. La última línea transforma el iterator en una lista.

Una diferencia entre usar csv y pandas es que csv no hace automáticamente la conversión a valores numéricos.

Ficheros JSON

El formato JSON está muy extendido y es muy útil a la hora de compartir datos con estructura compleja, como por ejemplo ficheros de configuración. Más allá de las aplicaciones científicas, es un estándar muy utilizado para intercambiar datos en la web.

Python viene con un módulo capaz de leer ficheros JSON. Partiendo de un fichero con el contenido:

{
    temperature=200,
    channels=[1,2],
    power=100
}
el módulo json permite leer y convertir el contenido en un objeto de Python:
import json
with open('fichero.csv', 'r') as fp:
    data = json.load(fp)
En este caso, data representa un diccionario con tres elementos: una lista y dos valores numéricos.