Ejemplos pandas

ventas_alimentacion

import pandas as pd

df = pd.read_csv("ventas_alimentacion.csv", index_col=0)
print(df)

# Estadísticas por ciudad
print(df.sum())    # total ventas por ciudad
print(df.mean())   # media por ciudad
print(df.max())    # máximo por ciudad


datos = {
    "Madrid":    [12450, 8760, 11230, 9340, 14560, 10870, 6540, 7890],
    "Barcelona": [9870,  7540, 8650,  7120, 11230, 12340, 5120, 6540],
    "Valencia":  [7340,  5980, 6780,  8450, 8760,  7650,  4870, 5230],
    "Sevilla":   [8920,  6120, 7450,  9210, 9870,  8430,  5340, 4980],
    "Zaragoza":  [4120,  3870, 4560,  3980, 5120,  3760,  2980, 3240],
    "Bilbao":    [5630,  4920, 6120,  4760, 7340,  9120,  3870, 4560],
    "Málaga":    [6780,  4560, 5340,  7890, 6540,  8760,  4120, 3870],
    "Murcia":    [3940,  3210, 4120,  5340, 4870,  4230,  2760, 2980],
}

indice = [
    "Aceite de oliva",
    "Pan y bollería",
    "Leche y lácteos",
    "Frutas y verduras",
    "Carne y charcutería",
    "Pescado y marisco",
    "Pasta, arroz y legumbres",
    "Conservas y enlatados",
]

df = pd.DataFrame(datos, index=indice)
print(df)

import pandas as pd

# ─────────────────────────────────────────────
#  DATAFRAME DE EJEMPLO
# ─────────────────────────────────────────────
data = {
    "Madrid":    [12450, 8760, 11230,  9340, 14560, 10870],
    "Barcelona": [ 9870, 7540,  8650,  7120, 11230, 12340],
    "Valencia":  [ 7340, 5980,  6780,  8450,  8760,  7650],
    "Sevilla":   [ 8920, 6120,  7450,  9210,  9870,  8430],
    "Bilbao":    [ 5630, 4920,  6120,  4760,  7340,  9120],
    "Murcia":    [ 3940, 3210,  4120,  5340,  4870,  4230],
}

indice = [
    "Aceite de oliva",
    "Pan y bollería",
    "Leche y lácteos",
    "Frutas y verduras",
    "Carne y charcutería",
    "Pescado y marisco",
]

df = pd.DataFrame(data, index=indice)

print(df)
print()


# ══════════════════════════════════════════════════════════════════
#  MÉTODO 1 — .loc[]  →  celda exacta por nombre
# ══════════════════════════════════════════════════════════════════
# .loc usa ETIQUETAS (nombres reales de filas y columnas).
# Sintaxis: df.loc["nombre_fila", "nombre_columna"]
resultado = df.loc["Leche y lácteos", "Madrid"]
print("1) .loc celda exacta:")
print(resultado)          # 11230
print()


# ══════════════════════════════════════════════════════════════════
#  MÉTODO 2 — .iloc[]  →  celda exacta por posición numérica
# ══════════════════════════════════════════════════════════════════
# .iloc usa POSICIONES enteras (0-based, igual que las listas).
# Fila 1 = "Pan y bollería", columna 2 = "Valencia"
resultado = df.iloc[1, 2]
print("2) .iloc celda exacta:")
print(resultado)          # 5980
print()


# ══════════════════════════════════════════════════════════════════
#  MÉTODO 3 — df["columna"]  →  columna completa (una Serie)
# ══════════════════════════════════════════════════════════════════
# Con un solo corchete y el nombre de columna obtienes una Serie.
# La Serie conserva el índice original del DataFrame.
resultado = df["Barcelona"]
print("3) Columna completa con df['col']:")
print(resultado)
print()


# ══════════════════════════════════════════════════════════════════
#  MÉTODO 4 — .loc["fila"]  →  fila completa por nombre
# ══════════════════════════════════════════════════════════════════
# Al pasar solo un nombre de fila, .loc devuelve una Serie
# donde el índice son los nombres de las columnas.
resultado = df.loc["Frutas y verduras"]
print("4) Fila completa con .loc:")
print(resultado)
print()


# ══════════════════════════════════════════════════════════════════
#  MÉTODO 5 — .iloc[:, col]  →  columna completa por posición
# ══════════════════════════════════════════════════════════════════
# El ":" significa "todas las filas".
# La columna 3 corresponde a "Sevilla" (0=Madrid, 1=Barcelona, ...)
resultado = df.iloc[:, 3]
print("5) Columna por posición con .iloc[:, 3]:")
print(resultado)
print()


# ══════════════════════════════════════════════════════════════════
#  MÉTODO 6 — .loc[inicio:fin]  →  rango de filas por nombre
# ══════════════════════════════════════════════════════════════════
# Con .loc los rangos son INCLUSIVOS en ambos extremos,
# es decir, se incluyen tanto "Pan y bollería" como "Frutas y verduras".
resultado = df.loc["Pan y bollería":"Frutas y verduras"]
print("6) Rango de filas con .loc (inclusivo):")
print(resultado)
print()


# ══════════════════════════════════════════════════════════════════
#  MÉTODO 7 — .iloc[inicio:fin]  →  rango de filas por posición
# ══════════════════════════════════════════════════════════════════
# Con .iloc los rangos son EXCLUSIVOS en el extremo derecho,
# igual que los slices de Python. iloc[2:5] devuelve filas 2, 3 y 4.
resultado = df.iloc[2:5]
print("7) Rango de filas con .iloc (exclusivo en el extremo derecho):")
print(resultado)
print()


# ══════════════════════════════════════════════════════════════════
#  MÉTODO 8 — .iloc[f1:f2, c1:c2]  →  submatriz por posición
# ══════════════════════════════════════════════════════════════════
# Selecciona filas 0, 1, 2  (0:3 → exclusivo en 3)
# y columnas 1, 2, 3        (1:4 → exclusivo en 4)
resultado = df.iloc[0:3, 1:4]
print("8) Submatriz con .iloc[0:3, 1:4]:")
print(resultado)
print()


# ══════════════════════════════════════════════════════════════════
#  MÉTODO 9 — .loc[rango_filas, lista_columnas]
# ══════════════════════════════════════════════════════════════════
# Combina un rango de filas (por nombre) con una lista de columnas
# específicas. Muy útil para extraer subconjuntos concretos.
resultado = df.loc["Aceite de oliva":"Leche y lácteos", ["Madrid", "Bilbao"]]
print("9) Rango de filas + columnas específicas con .loc:")
print(resultado)
print()


# ══════════════════════════════════════════════════════════════════
#  MÉTODO 10 — df[df["col"] > valor]  →  filtrado booleano
# ══════════════════════════════════════════════════════════════════
# La expresión df["Madrid"] > 10000 genera una Serie de True/False.
# Al pasarla al DataFrame, devuelve solo las filas donde es True.
resultado = df[df["Madrid"] > 10000]
print("10) Máscara booleana — ventas en Madrid > 10.000 €:")
print(resultado)
print()


# ══════════════════════════════════════════════════════════════════
#  MÉTODO 11 — .loc[condición, columnas]  →  filtro + selección
# ══════════════════════════════════════════════════════════════════
# Combina un filtro booleano con selección de columnas concretas.
# Primero filtra las filas y luego escoge qué columnas mostrar.
resultado = df.loc[df["Barcelona"] > 9000, ["Barcelona", "Madrid"]]
print("11) .loc con condición y selección de columnas:")
print(resultado)
print()


# ══════════════════════════════════════════════════════════════════
#  MÉTODO 12 — df[["c1", "c2", ...]]  →  varias columnas a la vez
# ══════════════════════════════════════════════════════════════════
# Con DOBLE corchete se pasa una lista de nombres.
# El resultado es un DataFrame (no una Serie), aunque elijas 1 columna.
resultado = df[["Madrid", "Sevilla", "Murcia"]]
print("12) Varias columnas con doble corchete:")
print(resultado)
print()


# ══════════════════════════════════════════════════════════════════
#  MÉTODO 13 — .iat[]  →  celda por posición (versión rápida)
# ══════════════════════════════════════════════════════════════════
# .iat es equivalente a .iloc para UN ÚNICO valor escalar.
# Es más eficiente que .iloc en DataFrames grandes porque
# no construye objetos intermedios.
resultado = df.iat[4, 0]
print("13) .iat — celda por posición (rápido):")
print(resultado)          # 14560  (fila 4 = "Carne", col 0 = "Madrid")
print()


# ══════════════════════════════════════════════════════════════════
#  MÉTODO 14 — .at[]  →  celda por etiqueta (versión rápida)
# ══════════════════════════════════════════════════════════════════
# .at es equivalente a .loc para UN ÚNICO valor escalar.
# Más rápido que .loc cuando solo necesitas un dato concreto.
resultado = df.at["Pescado y marisco", "Bilbao"]
print("14) .at — celda por etiqueta (rápido):")
print(resultado)          # 9120

import pandas as pd

# ─────────────────────────────────────────────
#  DATAFRAME DE EJEMPLO
# ─────────────────────────────────────────────
data = {
    "Madrid":    [12450, 8760, 11230,  9340, 14560, 10870],
    "Barcelona": [ 9870, 7540,  8650,  7120, 11230, 12340],
    "Valencia":  [ 7340, 5980,  6780,  8450,  8760,  7650],
    "Sevilla":   [ 8920, 6120,  7450,  9210,  9870,  8430],
    "Bilbao":    [ 5630, 4920,  6120,  4760,  7340,  9120],
    "Murcia":    [ 3940, 3210,  4120,  5340,  4870,  4230],
}

indice = [
    "Aceite de oliva",
    "Pan y bollería",
    "Leche y lácteos",
    "Frutas y verduras",
    "Carne y charcutería",
    "Pescado y marisco",
]

df = pd.DataFrame(data, index=indice)

print(df)
print()


# ══════════════════════════════════════════════════════════════════
#  MÉTODO 1 — df["col"] > valor  →  máscara booleana simple
# ══════════════════════════════════════════════════════════════════
# Una comparación sobre una columna devuelve una Serie de True/False.
# Al pasarla al DataFrame, actúa como "filtro de filas".
# Solo se muestran las filas donde la condición es verdadera.
mascara = df["Madrid"] > 10000
resultado = df[mascara]
print("1) Máscara booleana simple — Madrid > 10 000 €:")
print(resultado)
print()


# ══════════════════════════════════════════════════════════════════
#  MÉTODO 2 — & (AND)  →  dos condiciones simultáneas
# ══════════════════════════════════════════════════════════════════
# Para combinar condiciones usa & (AND) o | (OR).
# IMPORTANTE: cada condición debe ir entre paréntesis porque
# & tiene mayor precedencia que > y <.
resultado = df[(df["Madrid"] > 9000) & (df["Barcelona"] > 9000)]
print("2) Dos condiciones con & (AND) — Madrid > 9 000 y Barcelona > 9 000:")
print(resultado)
print()


# ══════════════════════════════════════════════════════════════════
#  MÉTODO 3 — | (OR)  →  al menos una condición verdadera
# ══════════════════════════════════════════════════════════════════
# Con | basta con que UNA de las condiciones sea True.
# Aquí: filas donde Bilbao supera 8 000 O Murcia supera 5 000.
resultado = df[(df["Bilbao"] > 8000) | (df["Murcia"] > 5000)]
print("3) Dos condiciones con | (OR) — Bilbao > 8 000 o Murcia > 5 000:")
print(resultado)
print()


# ══════════════════════════════════════════════════════════════════
#  MÉTODO 4 — ~  →  negación de una máscara
# ══════════════════════════════════════════════════════════════════
# El operador ~ invierte una máscara booleana (True → False y viceversa).
# Equivale al NOT lógico: devuelve las filas que NO cumplen la condición.
resultado = df[~(df["Valencia"] > 7000)]
print("4) Negación con ~ — filas donde Valencia NO supera 7 000 €:")
print(resultado)
print()


# ══════════════════════════════════════════════════════════════════
#  MÉTODO 5 — .isin()  →  filtrar por lista de valores
# ══════════════════════════════════════════════════════════════════
# .isin(lista) devuelve True en las filas cuyo valor está en la lista.
# Muy útil cuando tienes un conjunto de etiquetas permitidas.
categorias_interes = ["Aceite de oliva", "Carne y charcutería", "Pescado y marisco"]
resultado = df[df.index.isin(categorias_interes)]
print("5) .isin() — solo categorías de interés:")
print(resultado)
print()


# ══════════════════════════════════════════════════════════════════
#  MÉTODO 6 — .query()  →  filtrar con expresión de texto
# ══════════════════════════════════════════════════════════════════
# .query() acepta una cadena de texto con la condición en lenguaje
# casi natural. Más legible para condiciones complejas.
# Nota: si el nombre de columna tiene espacios, usa backticks (`col`).
resultado = df.query("Madrid > 10000 and Sevilla > 8000")
print("6) .query() — Madrid > 10 000 y Sevilla > 8 000:")
print(resultado)
print()


# ══════════════════════════════════════════════════════════════════
#  MÉTODO 7 — .filter(items=)  →  seleccionar columnas por nombre
# ══════════════════════════════════════════════════════════════════
# .filter() selecciona columnas (o filas con axis=0) por nombre exacto.
# No filtra por valores, sino por NOMBRE de columna.
resultado = df.filter(items=["Madrid", "Barcelona", "Murcia"])
print("7) .filter(items=) — columnas Madrid, Barcelona y Murcia:")
print(resultado)
print()


# ══════════════════════════════════════════════════════════════════
#  MÉTODO 8 — .filter(like=)  →  columnas cuyo nombre contiene texto
# ══════════════════════════════════════════════════════════════════
# like= selecciona columnas cuyo nombre CONTIENE la subcadena dada.
# axis=1 indica que buscamos en columnas; axis=0 buscaría en el índice.
resultado = df.filter(like="a", axis=1)   # columnas que contienen "a"
print("8) .filter(like='a') — columnas que contienen la letra 'a':")
print(resultado)
print()


# ══════════════════════════════════════════════════════════════════
#  MÉTODO 9 — .filter(regex=)  →  columnas por expresión regular
# ══════════════════════════════════════════════════════════════════
# regex= permite filtrar columnas cuyo nombre cumple un patrón regex.
# Aquí seleccionamos columnas que empiezan por 'M', 'B' o 'S'.
resultado = df.filter(regex="^(M|B|S)", axis=1)
print("9) .filter(regex=) — columnas que empiezan por M, B o S:")
print(resultado)
print()


# ══════════════════════════════════════════════════════════════════
#  MÉTODO 10 — .loc[condición, columnas]  →  filtro fila + columnas
# ══════════════════════════════════════════════════════════════════
# .loc admite una máscara booleana como selector de filas Y una lista
# de columnas como segundo argumento. El resultado es un sub-DataFrame.
resultado = df.loc[df["Bilbao"] > 6000, ["Bilbao", "Madrid", "Murcia"]]
print("10) .loc con condición + columnas — Bilbao > 6 000, ver Bilbao/Madrid/Murcia:")
print(resultado)
print()


# ══════════════════════════════════════════════════════════════════
#  MÉTODO 11 — .where()  →  mantiene forma, enmascara con NaN
# ══════════════════════════════════════════════════════════════════
# A diferencia de los filtros anteriores, .where() conserva el shape
# original del DataFrame. Las celdas que NO cumplen la condición
# se sustituyen por NaN (o por el valor que indiques en `other=`).
resultado = df.where(df > 8000)
print("11) .where(df > 8000) — valores < 8 000 sustituidos por NaN:")
print(resultado)
print()


# ══════════════════════════════════════════════════════════════════
#  MÉTODO 12 — .mask()  →  inverso de .where()
# ══════════════════════════════════════════════════════════════════
# .mask() es el opuesto de .where(): enmascara con NaN las celdas
# que SÍ cumplen la condición, manteniendo las que no la cumplen.
resultado = df.mask(df > 8000)
print("12) .mask(df > 8000) — valores > 8 000 sustituidos por NaN:")
print(resultado)
print()


# ══════════════════════════════════════════════════════════════════
#  MÉTODO 13 — filtro por índice con .str  →  texto en el índice
# ══════════════════════════════════════════════════════════════════
# Si el índice es de tipo cadena, puedes usar .str para filtrarlo.
# .str.contains() busca una subcadena; .str.startswith() un prefijo.
resultado = df[df.index.str.contains("y")]
print("13) Filtro de texto en el índice — categorías que contienen 'y':")
print(resultado)
print()


# ══════════════════════════════════════════════════════════════════
#  MÉTODO 14 — .nlargest() / .nsmallest()  →  top N por columna
# ══════════════════════════════════════════════════════════════════
# .nlargest(n, columna) devuelve las n filas con mayor valor en
# la columna indicada, ordenadas de mayor a menor.
# .nsmallest(n, columna) hace lo mismo para los menores valores.
resultado = df.nlargest(3, "Madrid")
print("14) .nlargest(3, 'Madrid') — top 3 categorías en Madrid:")
print(resultado)
print()

resultado = df.nsmallest(3, "Murcia")
print("    .nsmallest(3, 'Murcia') — bottom 3 categorías en Murcia:")
print(resultado)
print()

Publicado por

Juan Pablo Fuentes

Formador de programación y bases de datos