Seleccionar: [], loc e iloc
En resumen: En pandas [] selecciona columnas, loc selecciona filas y celdas por etiqueta, e iloc las selecciona por posición.
Problema
«El queso sube de precio»
El proveedor sube el precio del queso blanco de 7,90 € a 8,40 €. El gerente quiere tres cosas:
- una tabla pequeña para el mostrador con solo el nombre y el precio;
- el precio y el stock de un producto, sin buscar a ojo;
- el precio nuevo en la tabla, no en alguna copia aparte.
Esto es seleccionar: tomar una parte de la tabla, columnas, filas o una celda, y a veces cambiarla. pandas tiene tres herramientas para ello: [], loc e iloc.
La idea
Columnas: []
Ya tomas una columna con []. Si pones una lista de nombres entre los corchetes, obtienes una tabla con esas columnas, en ese orden:
Un nombre da una Serie con forma (25,). Una lista da un DataFrame con forma (25, 2), aunque la lista tenga una columna: products[['price']] es una tabla. Los corchetes dobles no son una sintaxis especial: los de fuera son para seleccionar, y los de dentro son para la lista.
La idea
Por etiqueta: loc
loc selecciona por etiquetas: primero las filas, luego las columnas, separadas por una coma. Con los nombres en el índice esto es «fila Queso blanco, columna price»:
- Una fila y una columna dan una celda: 7.9.
- Una fila sola da la fila entera como Serie. Sus etiquetas son ahora los nombres de las columnas.
- Las listas dan una tabla: el queso y la mantequilla con precio y stock.
Míralo
Un slice con loc incluye el final
Un slice con dos puntos (inicio:fin) funciona también en loc, pero hay una diferencia que confunde a todos:
loc[0:3] da 4 nombres: de la etiqueta 0 a la etiqueta 3 inclusive. Un slice de posiciones (iloc, listas de Python) se detiene antes del final y da 3.
La razón son las etiquetas. Con nombres en el índice, loc['Leche fresca':'Mantequilla'] da los lácteos, de la leche a la mantequilla. Nadie querría dejar fuera la mantequilla solo porque está escrita al final. ¿Cómo escribirías «hasta justo después de la mantequilla»?
La idea
Por posición: iloc
iloc selecciona por posición, como un arreglo de NumPy: la primera fila es 0, la última es -1. Las etiquetas no intervienen:
iloc[0, 1] es la primera fila, segunda columna: «Pan blanco». iloc[-1, 1] es el último producto: la tarjeta de regalo. iloc[:3, [1, 3]] son las tres primeras filas, las columnas en los lugares 1 y 3.
¿Cuál cuándo? loc cuando sabes lo que buscas: un producto, una columna por nombre. iloc cuando te importa el lugar: los 5 primeros, la última fila. Las posiciones se mueven en cuanto la tabla se ordena o se recorta, mientras que las etiquetas se quedan.
Pruébalo
Café en el almacén
El café es el producto con id 17. ¿Cuántos paquetes hay en stock? Pon id en el índice (by_id) y guarda el stock en coffee_stock como un solo número.
Solución
import pandas as pd
products = pd.read_csv('products.csv')
by_id = products.set_index('id')
coffee_stock = by_id.loc[17, 'stock']
print(coffee_stock)by_id = products.set_index('id') y coffee_stock = by_id.loc[17, 'stock'] da 15. La trampa es products.loc[17, 'stock']: sin set_index las etiquetas son los números desde 0, la etiqueta 17 es la fila 18, el té de menta, y la respuesta es 33. Sin la columna (by_id.loc[17]) obtienes la fila entera, no el número.
La idea
Una copia o la misma tabla
Ahora el precio nuevo. Recortas los lácteos y cambias en ellos el precio del queso. ¿Cambia products?
No: en dairy el queso es 8.4, pero en products sigue siendo 7.9. En pandas 3 cada trozo recortado se comporta como una copia. Cambiar el trozo no toca el original. Esto se llama Copy-on-Write: pandas no copia los datos enseguida, solo cuando uno de los dos objetos cambia.
Para cambiar la tabla, escribes en la tabla misma, con loc y la fila y la columna a la vez: products.loc[6, 'price'] = 8.4.
Míralo
Dos corchetes seguidos no escriben
La tentación es products['price'][6] = 8.4: la columna, luego la celda. Se parece a loc, pero no lo es:
El precio sigue siendo 7.9. products['price'] es un objeto aparte, una copia, y [6] = 8.4 escribe en ella. Esto se llama asignación encadenada (chained assignment). pandas 3 nunca la aplica a la tabla y muestra un aviso ChainedAssignmentError con una pista sobre .loc.
Hay una regla: escribes con un solo loc[fila, columna] = … sobre la tabla que quieres cambiar.
Más precisamente, para curiosos
En pandas 1 y 2 el mismo código a veces cambiaba la tabla y a veces no, según hubiera debajo una copia o una vista. Por eso existía un SettingWithCopyWarning, que decía «quizá». Lo encontrarás en artículos viejos y en respuestas por internet. En pandas 3 (2026) la regla es clara, y el aviso es historia. Si tu código tiene que funcionar también en una versión vieja, loc en un solo paso también es correcto allí.
La idea
Muchas filas a la vez: una máscara en loc
En el lugar de las filas de loc puedes poner una máscara: una columna de True y False, como las máscaras de NumPy. Entonces el cambio se aplica a cada fila donde la máscara es True. Dos productos están agotados y llega una entrega de 30 para cada uno:
empty.sum() cuenta los vacíos: 2. Después de la línea con loc, la banitsa y los pepinos tienen 30 cada uno. Usaremos mucho las máscaras sobre una tabla en la próxima lección, sobre filtros.
Pruébalo
Una entrega para los casi vacíos
Cada producto con menos de 10 en stock recibe 20 más. Guarda la máscara en low, y luego cambia su stock en products.
Solución
import pandas as pd
products = pd.read_csv('products.csv')
low = products['stock'] < 10
products.loc[low, 'stock'] = products.loc[low, 'stock'] + 20
print(products.loc[low, ['name', 'stock']])low = products['stock'] < 10 atrapa 4 productos, y products.loc[low, 'stock'] = products.loc[low, 'stock'] + 20 los repone: la banitsa y los pepinos pasan a 20, la sartén a 28 y los cuchillos a 25. Si recortas short = products.loc[low] y lo cambias, products se queda igual. La cadena products['stock'][low] = … tampoco escribe en la tabla.
Ejercicio
La tabla para el mostrador
Los nombres están en el índice de by_name. Cambia en by_name el precio de Queso blanco a 8.4. Luego guarda en counter la tabla para el mostrador: los lácteos de Leche fresca a Mantequilla, con las columnas price y stock.
Solución
import pandas as pd
products = pd.read_csv('products.csv')
by_name = products.set_index('name')
by_name.loc['Queso blanco', 'price'] = 8.4
counter = by_name.loc['Leche fresca':'Mantequilla', ['price', 'stock']]
counterby_name.loc['Queso blanco', 'price'] = 8.4 escribe en la tabla. counter = by_name.loc['Leche fresca':'Mantequilla', ['price', 'stock']] da 5 filas incluida la mantequilla, porque loc incluye el final. Con iloc[4:8] falta la mantequilla. Si cambias el precio en counter o con by_name['price']['Queso blanco'], el mostrador y el almacén muestran precios distintos, y by_name conserva el viejo.
Test
Ponte a prueba
Lecciones relacionadas
Sección «Lecciones relacionadas»- Se basa en: La primera tabla · Vectorización · Series y DataFrame
- Continúa en: Filtrar y ordenar · Columnas nuevas · Tipos y valores faltantes · Grupos: groupby
- Ejercicios sobre el tema: Tablas con pandas