0

我正在尝试在 pandas 数据帧上应用成对欧几里德距离计算的变体来生成边缘列表。

标准欧式距离计算可以是:

from scipy.spatial.distance import pdist
from scipy.spatial.distance import squareform
import pandas as pd
import numpy as np
# after dataframe is loaded
d_array = pdist(df, 'euclidean')
d_df = pd.DataFrame(squareform(d_array), index=df.index, columns= df.index)
d_df = d_df.where(np.triu(np.ones(d_df.shape)).astype(np.bool))
edge_list = d_df.stack()

我做了欧几里得距离计算的变体:

from math import *
import itertools

def arc_sub(a, b):
    HALF_CIRCUM = 180
    l = max(a, b)
    s = min(a, b)
    if l - s > HALF_CIRCUM:
        return s + HALF_CIRCUM * 2 - l
    else:
        return l - s

def arc_dist(df, pair):
    df_pair = df.loc[pair, :]
    x = df_pair.loc[pair[0], :]
    y = df_pair.loc[pair[1], ]
    return sqrt(sum(pow(arc_sub(a, b), 2) for a, b in zip(x, y)))

pairs = list(itertools.combinations(list(df.index), 2))
edge_list = pd.DataFrame([arc_dist(df, pair) for pair in pairs], index=pairs)

似乎我的变化比pdistof慢得多,scipy我猜这是由于循环通过配对列表。它占用的内存比pdist我猜想pdist一次将计算应用于所有对。有什么方法可以将我的距离计算也应用于所有对吗?

4

0 回答 0