如何在熊猫数据框中将欧几里得距离函数应用于groupby对象?

时间:2018-06-27 13:41:41

标签: python pandas dataframe euclidean-distance

我有一组对象及其随时间的位置。我想获得每个时间点对象之间的平均距离。数据帧示例如下:

QObject

我想要的最终结果是:

df2

time = [0, 0, 0, 1, 1, 2, 2]
x = [216, 218, 217, 280, 290, 130, 132]
y = [13, 12, 12, 110, 109, 3, 56]
car = [1, 2, 3, 1, 3, 4, 5]
df = pd.DataFrame({'time': time, 'x': x, 'y': y, 'car': car})
df

             x       y      car
     time
      0     216     13       1
      0     218     12       2
      0     217     12       3
      1     280     110      1
      1     290     109      3
      2     130     3        4
      2     132     56       5

关于如何进行的任何想法?我一直在尝试将scipy.spatial.distance函数应用于数据框,但是我不确定如何将其应用于df.groupby('time'),然后获取所有这些距离的平均值。 任何帮助表示赞赏!

3 个答案:

答案 0 :(得分:1)

对于我来说,使用apply或for循环并没有太大不同

l1=[]
l2=[]

for y,x in df.groupby('time'):
    v=np.triu(spatial.distance.cdist(x[['x','y']].values, x[['x','y']].values),k=0)

    v = np.ma.masked_equal(v, 0)
    l2.append(np.mean(v))
    l1.append(y)


pd.DataFrame({'ave':l2},index=l1)

Out[250]: 
         ave
0   1.550094
1  10.049876
2  53.037722

答案 1 :(得分:1)

您可以将点的数组传递到scipy.spatial.distaince.pdist,它将为i> j计算Xi和Xj之间的所有成对距离。然后取平均值。

import numpy as np
from scipy import spatial

df.groupby('time').apply(lambda x: spatial.distance.pdist(np.array(list(zip(x.x, x.y)))).mean())

输出:

time
0     1.550094
1    10.049876
2    53.037722
dtype: float64

答案 2 :(得分:0)

您还可以使用itertools包来定义自己的函数,如下所示:

 import itertools
 import numpy as np

 def combinations(series):
        l = list()
        for item in itertools.combinations(series,2):
            l.append(((item[0] - item[1])**2))
        return l

df2 = df.groupby('time').agg(combinations)
df2['avg_distance'] = [np.mean(np.sqrt(pd.Series(df2.iloc[k,0]) + 
pd.Series(df2.iloc[k,1]))) for k in range(len(df2))]

df2.avg_distance.to_frame()

然后,输出为:

    avg_distance
time    
0   1.550094
1   10.049876
2   53.037722