我试图在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)
似乎我的变化比pdist
的{{1}}慢得多,我猜这是由于在列表中循环。它占用的内存少于scipy
,我猜pdist
一次将计算应用于所有对。有什么方法可以将我的距离计算应用于所有对吗?