You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在不使用嵌套循环的情况下计算DataFrame中所有点对的距离?

问题描述

用户创建了如下示例DataFrame:

import pandas as pd

data = {'X': [10,20,30,40,50,60,70,80,90],
        'Y': [1,2,3,4,5,6,7,8,9],
       }

df_test = pd.DataFrame(data)

需要计算数据集中所有点对的距离(即每个点与其他所有点的距离),已定义欧氏距离函数:

import numpy as np
def dist(X1,Y1,X2,Y2):
    # 计算两点间距离
    d = np.sqrt((X2 - X1) * (X2 - X1) + (Y2 - Y1) * (Y2 - Y1))
    return d 

最初使用嵌套for循环实现,但该方法在大数据集下效率极低甚至导致崩溃(注:原代码存在列名错误、结果未正确收集的问题,已修正):

res = []

for i in range(0,len(df_test)):
    X1 = df_test.X[i]
    Y1 = df_test.Y[i]
    
    for j in range(0,len(df_test)):
        X2 = df_test.X[j]
        Y2 = df_test.Y[j]
        
        res.append(dist(X1,Y1,X2,Y2))
        print(res[-1])
    print()
无嵌套循环的高效解决方案

以下两种方法均基于向量运算,避免了Python层面的循环,大幅提升计算效率,适合大数据集:

方法1:利用NumPy广播机制

将DataFrame转换为NumPy数组后,通过广播实现批量计算:

import numpy as np
import pandas as pd

# 转换为NumPy数组,形状为(N, 2)
points = df_test.to_numpy()

# 利用广播计算所有点对的欧氏距离
# points[:, np.newaxis] 将形状变为(N, 1, 2),与原数组广播为(N, N, 2)
# 计算差值平方和后开根号,得到N×N的距离矩阵
distances = np.sqrt(np.sum((points[:, np.newaxis] - points)**2, axis=2))

# 输出结果矩阵
print(distances)

distances[i][j]对应第i个点与第j个点的距离,矩阵为对称矩阵(distances[i][j] = distances[j][i]),对角线为点到自身的距离0。

方法2:使用Scipy的封装函数

Scipy提供了专门的距离计算工具,代码更简洁且优化程度高:

from scipy.spatial.distance import pdist, squareform

# pdist计算所有两两不同点对的距离(返回一维数组,长度为N*(N-1)/2)
# squareform将其转换为对称的N×N距离矩阵
distances = squareform(pdist(df_test, metric='euclidean'))

print(distances)

metric='euclidean'指定计算欧氏距离,Scipy还支持其他距离类型(如曼哈顿距离、余弦距离等),只需修改参数即可。

内容的提问来源于stack exchange,提问作者Wishwa Rathnaweera

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 17:50:42