2015-11-07 51 views
0

假设我有一个数据帧我可以在数据帧上的行之间执行操作吗?

ID1 ID2 x    y   time 
0 0 1 34.337735 -76.3319716667 1446797582 
1 0 1 34.3841816667 -76.2837666667 1446796183 
2 0 2 34.49157 -76.1661133333 1446792969 
3 0 3 34.5275266667 -76.1151866667 1446791765 
4 0 3 34.5624816667 -76.0633883333 1446790559 

我想是捕获每个成员移动的距离,由ID1,ID2对唯一标识。

有无论如何我可以对数据框执行行操作?我最初的想法是使用df.as_matrix()将数据帧转换为矩阵,挑出唯一的ID,即矩阵的计算距离。

这看起来效率很低。有没有更好的方式,我可以用数据框做到这一点?

+0

是否存在多行数据为每个ID1,ID2对?换句话说,x和y随时间而变化? – paisanco

+0

是的,这是正确的。对于任意ID1,ID2对,至少有一行。如果有多个,那么x,y会随着时间而改变。 – user3600497

+0

可能是这样做的复杂方式,但你可以'groupby' ID1和ID2;然后*遍历组*压缩(使用'zip')''''和'y'到一个'xy'列,其中的值是点(x,y)。然后,将这个'xy'列移动1(使用'shift'),得到一个新的列'xyshift'。然后在这个“xyshift”列中的行轴上应用差分函数;并最终将它迭代地合并到你的数据框中或组成一个新的 – vmg

回答

0

如果你需要得到每个唯一的路径总长度,你可以做

pd.DataFrame(df.groupby(['ID1','ID2']).apply(lambda z:pathlength(z.x.values,z.y.values))) 

哪里pathlength

from math import sqrt 
def pathlength(x,y): 
    n = len(x) 
    lv = [sqrt((x[i]-x[i-1])**2 + (y[i]-y[i-1])**2) for i in range (1,n)] 
    L = sum(lv) 
    return L 

这给了我们

0 
ID1 ID2 
0 1 0.066940 
    2 0.000000 
    3 0.062489 
1

如果您想要计算每个时间步的距离,您可以执行以下操作

df[['x' , 'y']].apply(lambda x : np.linalg.norm(x) , axis = 1)

,另一方面

如果要计算以下

In [38]: 
df.groupby([df.ID1 , df.ID2])[['x' , 'y']]. 
apply(lambda x : np.linalg.norm(x.diff().dropna()) if len(x) > 1 else 0) 
Out[38]: 
ID1 ID2 
0 1  0.066940 
    2  0.000000 
    3  0.062489 
dtype: float64 

首先,你按你的ID列,然后检查成员的长度由每个成员的距离,你可以做如果长度大于1,那么这意味着该成员已经移动其他成员没有的明智。

您可以通过使用diff功能,这将产生na的第一列计算xy之间的差异,但你可以很容易地使用dropna功能删除它。

然后计算矢量长度可以很容易地使用该函数np.linalg.norm

也可以使用x.diff().iloc[1]代替x.diff().dropna()

+0

这是一个不错的解决方案,但我不想每个成员的总行程。我反而想要在每个时间步移动的距离。 – user3600497

+0

这更容易,你可以使用'df [['x','y']]。apply(lambda x:np.linalg.norm(x),axis = 1)' –

相关问题