HOWTO · Pandas

Tres formas de normalizar columnas numéricas de un DataFrame en Pandas

Compara la estandarización por la media (puntuación z), el escalado min-max y la normalización por cuantiles para columnas numéricas de DataFrame en Pandas, con fórmulas y ejemplos reutilizables.

En esta página

Para reescalar columnas numéricas de un DataFrame de Pandas, puedes elegir entre tres métodos: la normalización basada en la media (estandarización z) centra cada columna y la divide por su desviación estándar; el escalado min-max lleva cada columna no constante al intervalo 0–1; y la normalización por cuantiles asigna valores según su rango para aproximar una distribución común. La opción adecuada depende de la escala que necesite tu modelo, de su sensibilidad a los valores atípicos y de si las columnas deben tener distribuciones comparables.

Normalización de datos en Pandas

La normalización reescala los valores, mientras que la estandarización los centra en torno a una media y los expresa en unidades de desviación estándar. Esta guía presenta tres transformaciones por columna. Pandas no ofrece un único método específico de DataFrame para aplicar estas fórmulas, pero sus operaciones aritméticas y de ordenación permiten implementarlas fácilmente.

Los ejemplos usan el mismo DataFrame pequeño y determinista, con cuatro columnas numéricas. Cada transformación se aplica a lo largo de cada columna, por lo que se conservan los nombres de las columnas y los índices de las filas.

import pandas as pd


df = pd.DataFrame({
    "A": [1, 2, 3, 4],
    "B": [10, 20, 30, 40],
    "C": [4, 1, 3, 2],
    "D": [5, 5, 5, 5],
})

print(df)
   A   B  C  D
0  1  10  4  5
1  2  20  1  5
2  3  30  3  5
3  4  40  2  5

La columna D es constante para mostrar claramente su comportamiento en la sección sobre min-max. Los ejemplos siguientes son autónomos y vuelven a crear esta misma entrada.

Normalizar un DataFrame de Pandas con la normalización basada en la media

La fórmula basada en la media es (x - mean) / standard deviation y se calcula por separado para cada columna. Se trata de una estandarización z: la media de cada columna transformada queda cerca de cero y los valores se expresan en unidades de desviación estándar, en lugar de limitarse al intervalo 0–1. De forma predeterminada, Series.std() de Pandas usa la desviación estándar muestral (ddof=1); usa ddof=0 si tu cálculo requiere la desviación estándar poblacional.

import pandas as pd


df = pd.DataFrame({
    "A": [1, 2, 3, 4],
    "B": [10, 20, 30, 40],
    "C": [4, 1, 3, 2],
    "D": [5, 5, 5, 5],
})

mean_norm = df.apply(lambda column: (column - column.mean()) / column.std(), axis=0)
print(mean_norm.round(3))
       A      B      C   D
0 -1.162 -1.162  1.162 NaN
1 -0.387 -0.387 -1.162 NaN
2  0.387  0.387  0.387 NaN
3  1.162  1.162 -0.387 NaN

Esta transformación resulta útil cuando un método se beneficia de columnas centradas y con escalas comparables. Una columna constante tiene una desviación estándar de cero, por lo que esta fórmula produce valores ausentes en esa columna. Según tu aplicación, decide si conviene eliminar esa característica o tratarla por separado.

Normalizar un DataFrame de Pandas con la normalización min-max

Para cada columna, el escalado min-max usa (x - min) / (max - min). En toda columna no constante, el mínimo y el máximo pasan a ser 0 y 1, y los demás valores quedan proporcionalmente entre ambos. La función auxiliar de abajo usa su argumento df_input en todo momento y asigna 0 a las columnas constantes, una opción neutral habitual cuando una característica no presenta variación.

import pandas as pd


def minmax_norm(df_input):
    column_range = df_input.max() - df_input.min()
    scaled = (df_input - df_input.min()) / column_range
    return scaled.fillna(0)


df = pd.DataFrame({
    "A": [1, 2, 3, 4],
    "B": [10, 20, 30, 40],
    "C": [4, 1, 3, 2],
    "D": [5, 5, 5, 5],
})

print(minmax_norm(df).round(3))
       A      B      C    D
0  0.000  0.000  1.000  0.0
1  0.333  0.333  0.000  0.0
2  0.667  0.667  0.667  0.0
3  1.000  1.000  0.333  0.0

El escalado min-max es adecuado cuando se necesita un intervalo fijo. Como la escala depende del mínimo y el máximo observados, un valor extremo puede comprimir el resto de los valores de la columna en un intervalo estrecho. El fillna(0) final de la función asigna 0 a las columnas numéricas constantes, pero también sustituye por 0 todos los valores ausentes que ya hubiera en la entrada. Si prefieres imputar la media, rellena los valores ausentes antes de llamar a la función; por ejemplo, minmax_norm(df_input.fillna(df_input.mean())). Elige una política de imputación adecuada para tus datos.

Normalizar un DataFrame de Pandas con la normalización por cuantiles

La normalización por cuantiles es útil cuando se espera que las columnas compartan la misma distribución subyacente. Ordena cada columna, calcula la media de los valores ordenados en cada rango entre las columnas y después asigna esas medias de rango a las filas originales. A diferencia de los otros dos métodos, modifica los valores para alinear las distribuciones empíricas de las columnas; úsala solo cuando la suposición de una distribución común sea adecuada.

Esta implementación usa rank(method="min"): los valores empatados reciben el rango más bajo de su grupo. No promedia los rangos empatados, por lo que los empates pueden hacer que las distribuciones resultantes difieran. En el ejemplo común, la columna D es constante: sus cuatro valores empatan en el rango mínimo y, por tanto, se asignan a la misma media de rango, en vez de repartirse entre los rangos compartidos.

import numpy as np
import pandas as pd


def quantile_norm(df_input):
    sorted_values = np.sort(df_input.to_numpy(), axis=0)
    rank_means = sorted_values.mean(axis=1)
    rank_to_mean = pd.Series(rank_means, index=np.arange(1, len(rank_means) + 1))
    ranks = df_input.rank(method="min").stack().astype(int)
    return ranks.map(rank_to_mean).unstack()


df = pd.DataFrame({
    "A": [1, 2, 3, 4],
    "B": [10, 20, 30, 40],
    "C": [4, 1, 3, 2],
    "D": [5, 5, 5, 5],
})

print(quantile_norm(df).round(3))
       A      B      C     D
0   4.25   4.25  13.25  4.25
1   7.25   7.25   4.25  4.25
2  10.25  10.25  10.25  4.25
3  13.25  13.25   7.25  4.25

La columna constante D muestra por qué importa la suposición de una distribución común: todos sus valores repetidos reciben el rango mínimo y se asignan a 4.25, así que su distribución empírica no coincide con la de las otras columnas. Para características numéricas habituales, compara los métodos según su objetivo: elige las puntuaciones z para centrar y escalar por desviación estándar; min-max para obtener un intervalo acotado, teniendo en cuenta los valores atípicos; o la normalización por cuantiles cuando los datos justifican alinear las distribuciones de las columnas.