Pensamiento Computacional · Unidad 6 — Bibliotecas de Python
Pandas y DataFrames
Un DataFrame es una tabla con nombres de columna. Sirve para trabajar con datos reales: leer un CSV, filtrar filas, sacar promedios.
La explicación
La tabla
df = pd.DataFrame({
"nombre": ["ana", "luis", "sol"],
"nota": [9, 4, 7]
})
0 ana 9
1 luis 4
2 sol 7
Cada columna tiene nombre y todas sus celdas son del mismo tipo. Las filas se numeran solas.
Mirar
df.shape (filas, columnas)
len(df) cuántas filas
df.columns los nombres de las columnas
df.describe() estadísticas de las columnas numéricas
df.head() es lo primero que se hace siempre con un archivo nuevo: mirar qué tiene
antes de programar sobre él.
Una columna
df["nota"].mean() el promedio
df["nota"].max() el máximo
df["nota"].sum() la suma
Una columna funciona como un array de NumPy: df["nota"] * 2 duplica todas las notas
de una.
Filtrar filas
df["nota"] >= 7 no devuelve las notas: devuelve
una columna de True/False, una por fila. Y df[...] se
queda con las filas donde dio True.Para combinar condiciones se usa
& y | en vez de
and y or, y cada condición va entre paréntesis:
Una fila: iloc y loc
Con df["nota"] se saca una columna. Para sacar una fila hay dos formas, y la
diferencia entre ellas es el error más común del tema:
df.iloc[[0, 3]] las filas de las posiciones 0 y 3, como tabla
df.iloc[:2] las dos primeras (lo mismo que df.head(2))
df.loc[3] la fila cuyo índice es 3
df.loc[3, "nota"] una celda: la nota de la fila de índice 3
iloc cuenta posiciones, como los corchetes de una lista: la i es de «integer». En
cambio loc busca por el índice, la columna de números que pandas escribe a la
izquierda de la tabla. En una tabla recién leída los dos coinciden (el índice va 0, 1, 2…), y por
eso la diferencia pasa desapercibida hasta que se filtra o se ordena.
df = pd.DataFrame({
"nombre": ["ana", "luis", "sol", "teo", "eva"],
"comision": ["A", "B", "A", "B", "A"],
"nota": [6, 9, 4, 7, 8]
})
aprobados = df[df["nota"] >= 7]
print(aprobados)
print(aprobados.iloc[0]["nombre"])
print(aprobados.loc[3, "nombre"])
1 luis B 9
3 teo B 7
4 eva A 8
luis
teo
aprobados.iloc[0] es luis (el primero que quedó) y
aprobados.loc[3] es teo (el que tenía índice 3). Y aprobados.loc[0] da
KeyError: 0: la fila de índice 0 era ana, que no aprobó. Regla práctica: si querés
«el primero», «el último», «los tres de arriba», es iloc; si querés una fila por su
etiqueta, es loc.
loc también sirve para cambiar una celda: df.loc[2, "nota"] = 5
le pone 5 a la nota de la fila de índice 2 en la misma tabla.
Ordenar: sort_values
df = pd.DataFrame({
"nombre": ["ana", "luis", "sol", "teo", "eva"],
"comision": ["A", "B", "A", "B", "A"],
"nota": [6, 9, 4, 7, 8]
})
orden = df.sort_values("nota", ascending=False)
print(orden)
print(orden.iloc[0]["nombre"], orden.loc[0, "nombre"])
1 luis B 9
4 eva A 8
3 teo B 7
0 ana A 6
2 sol A 4
luis ana
sort_values(columna) ordena las filas por esa columna, de menor a mayor;
con ascending=False, de mayor a menor. Igual que sorted en el tema 4.3,
devuelve una tabla nueva y deja df como estaba: si no se guarda el resultado,
el orden se pierde.
orden.iloc[0] es luis (la nota más alta) y
orden.loc[0] es ana (la que tenía índice 0, que ahora está cuarta). «El de nota más
alta» se pide con iloc[0].
Para ordenar por dos columnas se pasan listas: df.sort_values(by=["comision", "nota"],
ascending=[True, False]) agrupa por comisión (A antes que B) y, adentro de cada una, pone
las notas de mayor a menor: eva, ana, sol, luis, teo.
Contar: value_counts
A 3
B 2
Name: count, dtype: int64
Cuenta cuántas veces aparece cada valor de una columna, de la más frecuente a la menos. Es el diccionario contador del tema 4.5 en una sola línea, y es lo primero que se mira en una columna de categorías: cuántos por comisión, por carrera, por producto.
Archivos CSV
df.to_csv("salida.csv", index=False) guardar
Un CSV es un archivo de texto con valores separados por comas, y es el formato estándar para
datos. Compará esto con la unidad 5: lo que allá eran diez líneas con open,
strip y split, acá es una sola — y encima convierte los tipos solo.
El index=False al guardar evita que agregue una columna extra con los números de
fila, que casi nunca se quiere.
Un archivo notas.csv tiene columnas nombre y nota. Escribir el código que muestre cuántos aprobaron y el promedio de los aprobados.
df = pd.read_csv("notas.csv")
print(df.head()) # mirar antes de programar
aprobados = df[df["nota"] >= 7]
print("Aprobaron:", len(aprobados))
print("Promedio:", aprobados["nota"].mean())
Con la tabla de ana (9), luis (4) y sol (7): aprobaron 2, y el promedio de ellos es (9 + 7) / 2 = 8.0.
head() antes de todo. Los nombres de las columnas de un archivo
real casi nunca son los que uno imagina: pueden tener mayúsculas, acentos o espacios
("Nota Final" en vez de "nota"). Si programás a ciegas, el
KeyError aparece recién al correr. Mirar primero cuesta dos segundos.
Compará con hacer lo mismo a mano, como en la unidad 5: abrir el archivo, saltear el encabezado, separar cada línea por comas, convertir la nota, acumular... quince líneas, y todas con posibilidad de error. Para eso existen las bibliotecas.
Control: len(aprobados) nunca puede ser mayor que len(df), y
el promedio de los aprobados tiene que ser mayor o igual que 7. Si no, el filtro está mal.
Un archivo ventas.csv tiene las columnas producto, mes y monto. Calcular el total facturado por producto, el total por mes, cuál fue el mes de mayor facturación y el total general.
El archivo:
lapicera,enero,1500
cuaderno,enero,2400
lapicera,febrero,900
cuaderno,febrero,3000
goma,enero,1000
Leerlo es una línea:
df = pd.read_csv("ventas.csv")
read_csv hace solo lo que en la unidad 5 costaba diez líneas: abre el archivo, usa la primera fila como nombres de columna, separa por comas, y convierte los números a números. Que monto quede como número y no como texto es lo que permite sumarlo después.
Conviene mirar los tipos antes de calcular nada:
# producto object (texto)
# mes object
# monto int64 (numero: se puede sumar)
El total por producto, con groupby:
groupby se lee literal: agrupá por producto, tomá la columna monto, sumala. Es el reemplazo del diccionario acumulador de la unidad 4, en una línea.
El resultado:
goma 1000
lapicera 2400
El que más facturó, sin ordenar ni recorrer:
por_producto.max() # 5400 -> CUANTO
idxmax() devuelve el índice del máximo, que acá es el nombre del producto. Es distinto de max(), que devolvería el valor 5400. Confundirlos es el error más común de esta unidad: uno da "quién" y el otro da "cuánto".
El total por mes es el mismo patrón cambiando la columna:
por_mes.idxmax() # 'enero'
febrero 3900 (900 + 3000)
mejor mes: enero
El total general:
El control que hay que hacer siempre con un groupby: los subtotales tienen que sumar el total.
por mes: 4900 + 3900 = 8800 ✓
total general: 8800 ✓
Si no cierra, alguna fila se perdió o se contó dos veces. Pasa, por ejemplo, cuando hay nombres con espacios sobrantes: "goma" y "goma " son dos productos distintos para pandas, y el groupby los separa sin avisar. Conviene revisar con df["producto"].unique() cuántos productos distintos encontró.
La comparación con hacerlo a mano, que es lo que este ejercicio muestra: con open, split y un diccionario son unas quince líneas y hay que manejar el encabezado, las conversiones y las líneas vacías. Con pandas son cuatro, y los casos raros ya están resueltos.
Dónde se pierde el punto: contestar el valor cuando piden el nombre. "¿Cuál fue el mes de mayor facturación?" se contesta "enero", no "4900"; y para eso va idxmax().
Dónde se cae la mayoría
- Combinar condiciones con and en vez de &, o sin paréntesis alrededor de cada una.
- Programar sobre un CSV sin haber mirado antes df.head(): los nombres de columna casi nunca son los que uno supone.
- Guardar con to_csv sin index=False y que aparezca una columna de más.
- Usar loc[0] para pedir «la primera fila» de una tabla filtrada u ordenada: loc busca por índice, y la primera posición se pide con iloc[0].
- Llamar a sort_values sin guardar el resultado: devuelve una tabla nueva y df queda como estaba.
Hasta acá la explicación. La práctica es la otra mitad: 7 ejercicios de este tema, en cuatro niveles, que no te dicen sólo si está bien al final sino que te corrigen en cada paso y te explican por qué. Además trae una animación que muestra la idea en movimiento.
Practicar Pandas y DataFrames →Dónde entra este tema en el parcial
- Segundo parcial — La tabla de aprobados20 puntos · resuelto paso a paso
Los otros temas de la unidad 6
Bibliotecas de Python