HOWTO · NumPy

Calcule a distância euclidiana em Python

Este tutorial demonstra como calcular a distância euclidiana em python

Nesta página

Para dois arrays NumPy que representam pontos com o mesmo número de coordenadas, calcule a distância euclidiana com np.linalg.norm(point_a - point_b). A subtração cria as diferenças entre coordenadas, e a norma L2 do vetor reduz essas diferenças a uma única distância não negativa.

Entenda a fórmula da distância euclidiana

Para os pontos (a=(a_1,\ldots,a_n)) e (b=(b_1,\ldots,b_n)), a distância euclidiana é a raiz quadrada da soma dos quadrados das diferenças de coordenadas:

Fórmula da distância euclidiana: a raiz quadrada da soma dos quadrados das diferenças de coordenadas.

No NumPy, np.linalg.norm(a - b) expressa essa definição diretamente. Com um array de diferenças unidimensional e sem argumento ord, np.linalg.norm calcula sua norma 2. As duas entradas devem descrever pontos em dimensões compatíveis para que a subtração tenha o significado pretendido.

Prepare as coordenadas de entrada

As posições das coordenadas devem descrever os mesmos eixos na mesma ordem: compare a primeira coordenada de um ponto com a primeira do outro, e assim por diante. Represente um ponto como um array unidimensional com forma (coordinates,). Um par de arrays com forma (3,), por exemplo, representa dois pontos no mesmo sistema de coordenadas tridimensional; não representa três distâncias independentes.

Tuplas e listas podem ser convertidas com np.asarray(values, dtype=float) antes da subtração. O tipo de ponto flutuante aceita coordenadas inteiras ou decimais e evita o estouro de inteiros sem sinal quando uma coordenada é menor que a correspondente. Se as entradas já forem arrays NumPy adequados de ponto flutuante, a conversão é desnecessária. Evite achatar dados multidimensionais arbitrários apenas para fazer as formas coincidirem, pois isso pode ocultar um erro na estrutura de entrada em vez de corrigi-lo.

Os exemplos abaixo foram executados com Python 3.14.7, NumPy 2.5.3 e SciPy 1.18.1. As APIs demonstradas são interfaces estabelecidas, mas uma aplicação ainda deve usar versões compatíveis com o ambiente Python que ela oferece suporte. SciPy é opcional, a menos que seja usado o método SciPy ou ferramentas de distância por pares.

Calcule a distância entre dois pontos

O exemplo verificado a seguir compara a expressão de norma recomendada com a fórmula explícita, uma formulação por produto escalar, math.dist da biblioteca padrão e scipy.spatial.distance.euclidean do SciPy. Os cinco cálculos produzem o mesmo resultado para este par de pontos.

"""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

A fórmula explícita usa conceitualmente a elevação ao quadrado elemento a elemento com NumPy, seguida de uma soma e uma raiz quadrada. A forma exponencial do exemplo mantém o cálculo completo em uma expressão. A variante de produto escalar calcula a mesma soma de quadrados porque np.dot(delta, delta) multiplica as diferenças correspondentes e as soma.

Use np.linalg.norm quando os pontos já forem arrays ou fizerem parte de um cálculo NumPy maior. Ela comunica claramente a operação vetorial sem explicitar a redução.

Calcule distâncias por linha com axis=1

Para vários pontos armazenados como linhas de um array bidimensional, subtraia um ponto de referência e defina axis=1. O NumPy transmite o array de referência pelas linhas, enquanto axis=1 instrui np.linalg.norm a retornar uma norma por linha, em vez de uma norma para toda a 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]

A primeira linha é igual à referência, portanto sua distância é zero. O segundo resultado é a distância calculada no exemplo de um par. Esse padrão cobre distâncias de um para muitos; para todas as distâncias por pares entre duas coleções, use uma rotina dedicada como scipy.spatial.distance.cdist em vez de criar um grande intermediário transmitido sem considerar o uso de memória.

Escolha entre NumPy, math.dist e SciPy

O melhor método depende do código ao redor, e não de uma afirmação universal de velocidade:

  • Use np.linalg.norm(a - b) para arrays NumPy, fluxos de trabalho vetorizados e cálculos por linha com axis.
  • Use math.dist(a, b) para um par de iteráveis de coordenadas Python comuns quando NumPy não é necessário em outra parte.
  • Use scipy.spatial.distance.euclidean(a, b) quando SciPy já for uma dependência ou quando o cálculo pertencer ao conjunto mais amplo de ferramentas de distância do SciPy.
  • Use a fórmula explícita de soma dos quadrados ou o produto escalar ao ensinar, auditar ou adaptar o cálculo subjacente. Eles não tornam o resultado mais euclidiano do que a expressão de norma.

Converter listas com np.asarray(..., dtype=float) é útil antes da subtração NumPy porque listas Python não oferecem subtração elemento a elemento. math.dist aceita diretamente iteráveis de coordenadas de mesmo comprimento, enquanto as opções NumPy e SciPy exigem seus respectivos pacotes instalados.

Lide com formas incompatíveis e tipos de dados numéricos

Dois pontos individuais devem ter o mesmo número de coordenadas. Formas unidimensionais incompatíveis não podem ser transmitidas juntas, portanto o NumPy gera um ValueError antes de poder calcular uma distância.

"""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,)

Verifique as formas antes da subtração quando as dimensões vierem de entrada do usuário ou de dados externos. Para distâncias por linha, um array de pontos com forma (rows, coordinates) é compatível com uma referência de forma (coordinates,); outra forma pode transmitir de modo não intencional ou falhar.

Também converta coordenadas de inteiros sem sinal para um tipo com sinal ou de ponto flutuante antes de subtrair. A subtração sem sinal pode sofrer estouro em vez de representar uma diferença negativa de coordenadas, tornando a norma subsequente incorreta. Usar arrays de ponto flutuante nos exemplos evita esse problema e aceita coordenadas não inteiras.

Para um par de pontos NumPy com dimensões iguais, np.linalg.norm(point_a - point_b) é o padrão conciso. Adicione axis=1 para distâncias por linha e valide formas e tipos de dados sempre que a estrutura de entrada não estiver garantida.