HOWTO · NumPy

Calcular la distancia euclidiana en Python

Este tutorial demuestra cómo calcular la distancia euclidiana en python

En esta página

Para dos arrays de NumPy que representan puntos con el mismo número de coordenadas, calcule la distancia euclidiana con np.linalg.norm(point_a - point_b). La resta crea las diferencias de coordenadas y la norma L2 del vector las reduce a una única distancia no negativa.

Entender la fórmula de la distancia euclidiana

Para los puntos (a=(a_1,\ldots,a_n)) y (b=(b_1,\ldots,b_n)), la distancia euclidiana es la raíz cuadrada de la suma de las diferencias de coordenadas al cuadrado:

Fórmula de la distancia euclidiana: la raíz cuadrada de la suma de las diferencias de coordenadas al cuadrado.

En NumPy, np.linalg.norm(a - b) expresa esa definición directamente. Con un array de diferencias unidimensional y sin argumento ord, np.linalg.norm calcula su norma 2. Ambas entradas deben describir puntos con dimensiones compatibles para que la resta tenga el significado previsto.

Preparar las coordenadas de entrada

Las posiciones de las coordenadas deben describir los mismos ejes y en el mismo orden: compare la primera coordenada de un punto con la primera del otro, y así sucesivamente. Represente un punto como un array unidimensional con forma (coordinates,). Por ejemplo, dos arrays con forma (3,) representan dos puntos en el mismo sistema de coordenadas tridimensional; no representan tres distancias independientes.

Las tuplas y listas se pueden convertir con np.asarray(values, dtype=float) antes de restarlas. El tipo de punto flotante acepta coordenadas enteras o decimales y evita el desbordamiento de enteros sin signo cuando una coordenada es menor que su equivalente. Si las entradas ya son arrays de NumPy de punto flotante adecuados, la conversión no es necesaria. Evite aplanar datos multidimensionales arbitrarios solo para que coincidan las formas, porque puede ocultar un error de estructura de entrada en lugar de corregirlo.

Los ejemplos siguientes se ejecutaron con Python 3.14.7, NumPy 2.5.3 y SciPy 1.18.1. Las API mostradas son interfaces establecidas, pero una aplicación debe usar versiones compatibles con su propio entorno de Python admitido. SciPy es opcional salvo que se empleen el método de SciPy o herramientas de distancia por pares.

Calcular la distancia entre dos puntos

El siguiente ejemplo verificado compara la expresión de norma recomendada con la fórmula explícita, una formulación de producto escalar, el método de biblioteca estándar math.dist y scipy.spatial.distance.euclidean de SciPy. Los cinco cálculos producen el mismo resultado para este par de puntos.

"""Verify equivalent Euclidean-distance APIs for one pair of points."""

import math

import numpy as np
from scipy.spatial import distance

point_a = np.array([1.0, 2.0, 3.0])
point_b = np.array([4.0, 5.0, 6.0])

print(f"np.linalg.norm: {np.linalg.norm(point_a - point_b)}")
print(f"formula: {np.sqrt(np.sum((point_a - point_b) ** 2))}")
delta = point_a - point_b
print(f"dot product: {np.sqrt(np.dot(delta, delta))}")
print(f"math.dist: {math.dist(point_a, point_b)}")
print(f"distance.euclidean: {distance.euclidean(point_a, point_b)}")
np.linalg.norm: 5.196152422706632
formula: 5.196152422706632
dot product: 5.196152422706632
math.dist: 5.196152422706632
distance.euclidean: 5.196152422706632

La fórmula explícita usa conceptualmente la elevación al cuadrado elemento a elemento con NumPy, seguida de una suma y una raíz cuadrada. La forma con exponente del ejemplo mantiene el cálculo completo en una expresión. La variante de producto escalar calcula la misma suma de cuadrados porque np.dot(delta, delta) multiplica y suma las diferencias correspondientes.

Use np.linalg.norm cuando los puntos ya sean arrays o formen parte de un cálculo mayor con NumPy. Comunica con claridad la operación vectorial sin desarrollar la reducción.

Calcular distancias por fila con axis=1

Para varios puntos almacenados como filas de un array bidimensional, reste un punto de referencia y establezca axis=1. NumPy difunde el array de referencia por las filas, mientras que axis=1 indica a np.linalg.norm que devuelva una norma por fila en vez de una norma para toda la matriz.

"""Verify row-wise distances from several points to one reference point."""

import numpy as np

points = np.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
reference = np.array([1.0, 2.0, 3.0])

print(np.linalg.norm(points - reference, axis=1))
[0.         5.19615242]

La primera fila es igual a la referencia, por lo que su distancia es cero. El segundo resultado es la distancia calculada en el ejemplo de un par. Este patrón cubre distancias de uno a muchos; para todas las distancias por pares entre dos colecciones, use una rutina especializada como scipy.spatial.distance.cdist en vez de crear un gran array intermedio difundido sin tener en cuenta el uso de memoria.

Elegir entre NumPy, math.dist y SciPy

El mejor método depende del código circundante, no de una afirmación universal sobre velocidad:

  • Use np.linalg.norm(a - b) para arrays de NumPy, flujos vectorizados y cálculos por fila con axis.
  • Use math.dist(a, b) para un par de iterables de coordenadas ordinarios de Python cuando NumPy no sea necesario por otros motivos.
  • Use scipy.spatial.distance.euclidean(a, b) cuando SciPy ya sea una dependencia o el cálculo pertenezca a las herramientas de distancia más amplias de SciPy.
  • Use la fórmula explícita de suma de cuadrados o el producto escalar para enseñar, auditar o adaptar el cálculo subyacente. No hacen el resultado más euclidiano que la expresión de norma.

Convertir listas con np.asarray(..., dtype=float) es útil antes de la resta de NumPy porque las listas de Python no admiten resta elemento a elemento. math.dist acepta directamente iterables de coordenadas de igual longitud, mientras que las opciones de NumPy y SciPy requieren sus respectivos paquetes instalados.

Manejar formas incompatibles y tipos de datos numéricos

Dos puntos individuales deben tener el mismo número de coordenadas. Las formas unidimensionales incompatibles no se pueden difundir juntas, por lo que NumPy genera un ValueError antes de poder calcular una distancia.

"""Capture the diagnostic for points with incompatible dimensions."""

import numpy as np

point_a = np.array([1.0, 2.0])
point_b = np.array([3.0, 4.0, 5.0])

try:
    np.linalg.norm(point_a - point_b)
except ValueError as error:
    print(f"ValueError: {error}".rstrip())
ValueError: operands could not be broadcast together with shapes (2,) (3,)

Compruebe las formas antes de restar cuando las dimensiones procedan de la entrada de usuario o de datos externos. Para distancias por fila, un array de puntos con forma (rows, coordinates) es compatible con una referencia de forma (coordinates,); otra forma puede difundirse de modo no previsto o fallar.

Convierta también las coordenadas enteras sin signo a un tipo con signo o de punto flotante antes de restar. La resta sin signo puede desbordarse en lugar de representar una diferencia de coordenadas negativa, lo que hace incorrecta la norma posterior. Los arrays de punto flotante de los ejemplos evitan ese problema y admiten coordenadas no enteras.

Para un par de puntos de NumPy con dimensiones iguales, np.linalg.norm(point_a - point_b) es la opción predeterminada concisa. Añada axis=1 para distancias por fila y valide las formas y los tipos de datos cuando la estructura de entrada no esté ya garantizada.