Pandas práctico(1): Series y DataFrames

En una serie anterior cubrimos los fundamentos de NumPy, ahora es momento de lidiar con otra herramienta importante frecuentemente usada en análisis de datos: Pandas.

Pandas es una biblioteca para manipulación y análisis de datos que te permite manipular datos heterogéneos en forma tabular (en contraste con NumPy, diseñado para trabajar con datos numéricos homogéneos en forma de array). Incluye estructuras de datos y características de manipulación de datos que hacen que limpiar y analizar datos sea una tarea rápida y fácil.

Originalmente fue desarrollado por Wes McKinney (2008), pero a lo largo de los años ha ganado una comunidad enormemente solidaria que continuamente invierte en mejorar la herramienta.

Este artículo será la introducción a una serie donde aprenderemos cómo trabajar con Pandas usando un enfoque práctico. Si apenas estás comenzando, recomiendo ejecutar un notebook de Jupyter a la par y probar los ejemplos.

Perfecto, comencemos nuestro viaje hablando sobre las dos estructuras de datos más importantes en Pandas: Series y DataFrames.

# Antes de proceder, necesitamos importar pandas. El alias más común para esto es pd
import pandas as pd

Series

Una Serie es una colección similar a un array que contiene una secuencia de valores y su conjunto asociado de etiquetas (llamado índice).

# Puedes crear una serie alimentando una lista a pd.Series
simple_series = pd.Series([2,4,6,8,10])
print(simple_series)
0     2
1     4
2     6
3     8
4    10
dtype: int64

La columna de la izquierda es el índice de nuestra serie, y la columna de la derecha son los valores. No proporcionamos un índice durante la creación, así que NumPy creó un índice por defecto que consiste en enteros comenzando en 0. Puedes pasar un parámetro de índice durante la creación así:

series = pd.Series([2,4,6,8,10], index=['dos', 'quatre', 'six', 'oito', 'dieci'])
print(series)
dos        2
quatre     4
six        6
oito       8
dieci     10
dtype: int64
# Puedes recuperar el índice usando el atributo .index de la serie
print(series.index)
Index(['dos', 'quatre', 'six', 'oito', 'dieci'], dtype='object')

Puedes recuperar elementos de la serie usando el valor de índice respectivo como si estuvieras obteniendo elementos de un diccionario estándar de Python:

# Obtengamos el elemento cuyo índice es 'oito'
element = series['oito']
print(element)
8
# Podemos recuperar más de un elemento si proporcionamos un array de índices
elements = series[['dieci', 'dos', 'six']]
print(elements)
dieci    10
dos       2
six       6
dtype: int64

Una forma alternativa de crear Series es proporcionando un diccionario como argumento durante la creación:

num_data = {'dos': 2,
            'quatre': 4,
            'six': 6,
            'oito': 8,
            'dieci': 10}

other_series = pd.Series(num_data)
print(other_series)
dos        2
quatre     4
six        6
oito       8
dieci     10
dtype: int64
# Puedes alterar el orden proporcionando un argumento de índice adicional, solo ten cuidado:
# Si proporcionas en la lista un elemento que no está en el diccionario, se llenará con NA
other_series = pd.Series(num_data, index=['doce', 'dieci', 'oito', 'six', 'quatre', 'dos'])
print(other_series)
doce       NaN
dieci     10.0
oito       8.0
six        6.0
quatre     4.0
dos        2.0
dtype: float64
# Como último detalle, puedes asignar nombres tanto al índice como a los valores de una serie
other_series.name = 'Numbers'
other_series.index.name = 'Names'
print(other_series)
Names
doce       NaN
dieci     10.0
oito       8.0
six        6.0
quatre     4.0
dos        2.0
Name: Numbers, dtype: float64

DataFrames

Los DataFrames representan un arreglo rectangular de datos que consiste en columnas. Cada columna puede tener un tipo de dato diferente: algunas pueden representar datos numéricos como temperaturas o edades, y otras pueden contener cadenas de texto o entradas booleanas. Los DataFrames cuentan tanto con un índice de columna como de fila.

# Los DataFrames también pueden ser creados a partir de diccionarios

poke_data = {'Name': ['Abra', 'Koffing', 'Ditto', 'Pikachu'],
             'Type': ['Psychic', 'Poison', 'Normal', 'Electric'],
             'Base speed': [90, 35, 48, 90],
             'Learns transform': [False, False, True, False]}

poke_frame = pd.DataFrame(poke_data)
poke_frame
Name Type Base speed Learns transform
0 Abra Psychic 90 False
1 Koffing Poison 35 False
2 Ditto Normal 48 True
3 Pikachu Electric 90 False
# Puedes recuperar columnas del dataframe (como un objeto Series) usando ya sea sintaxis similar a diccionario o por atributo

poke_speeds = poke_frame['Base speed']
print(poke_speeds)
0    90
1    35
2    48
3    90
Name: Base speed, dtype: int64
poke_types = poke_frame.Type
print(poke_types)
0     Psychic
1      Poison
2      Normal
3    Electric
Name: Type, dtype: object
# Las filas pueden ser recuperadas usando loc, puedes usar la función loc y proporcionar el índice correcto

abra_data = poke_frame.loc[0]
print(abra_data)
Name                   Abra
Type                Psychic
Base speed               90
Learns transform      False
Name: 0, dtype: object
# Puedes actualizar los valores de una columna usando asignación estándar
# Actualicemos los nombres con versiones 'lindas'

poke_frame['Name'] = ['Cute Abra', 'Cute Koffing', 'Cute Ditto', 'Cute Pikachu']
poke_frame
Name Type Base speed Learns transform
0 Cute Abra Psychic 90 False
1 Cute Koffing Poison 35 False
2 Cute Ditto Normal 48 True
3 Cute Pikachu Electric 90 False
# Si realizas la asignación a una columna que aún no existe, se creará una nueva
poke_frame['Yellow'] = [True, False, False, True]
poke_frame
Name Type Base speed Learns transform Yellow
0 Cute Abra Psychic 90 False True
1 Cute Koffing Poison 35 False False
2 Cute Ditto Normal 48 True False
3 Cute Pikachu Electric 90 False True
# Y finalmente, si quieres deshacerte de una columna específica puedes usar del
del poke_frame['Yellow']
poke_frame
Name Type Base speed Learns transform
0 Cute Abra Psychic 90 False
1 Cute Koffing Poison 35 False
2 Cute Ditto Normal 48 True
3 Cute Pikachu Electric 90 False

Estos son solo los primeros pasos

Creo que es suficiente para una introducción. Todo lo que necesitas recordar es que los DataFrames representan datos tabulares y las Series representan solo una fila (o columna) de datos a la vez.

En los próximos artículos aprenderemos algunas técnicas útiles para manipular y analizar datos. Todo ese conocimiento se construye sobre las bases que acabamos de aprender, así que siéntete libre de experimentar un poco por tu cuenta para solidificar tu comprensión. Crea un par de dataframes y series con datos que conozcas: comestibles, mascotas, partículas fundamentales.

¡Gracias por leer!

Qué hacer después

Juan Luis Orozco Villalobos

¡Hola! Soy Juan, ingeniero de software y consultor en Budapest. Me especializo en computación en la nube e IA, y me encanta ayudar a otros a aprender sobre tecnología e ingeniería