我正在处理以下数据框:
id1 id2 lat lon
0 1 2 18.46290 -66.10301
1 1 2 37.549 -71.477
2 1 2 41.490 -71.326
3 0 0 0.0 0.0
4 1 3 42.058 -70.577
5 1 3 42.402 -70.642
6 1 3 41.589 -71.281
7 1 3 37.649 -71.440
8 0 0 0.0 0.0
9 2 2 18.462 -66.103
10 2 2 18.44857 -66.089
11 2 2 42.242 -70.97
12 0 0 0.0 0.0
以上数据是轨迹数据,我想找到所有在一个城市开始或结束的轨迹,比如NYC。
每个轨迹都有多个点,轨迹由上面df中的所有0行分隔。
因此,0-2行是一个轨迹,4-7行是另一个轨道,依此类推。 (即使需要删除所有0行,“id1”和“id2”一起标识不同的轨迹,就像我们在id1或id2发生变化时所看到的那样,我们正在获得新的轨迹)。
我有另一个df,比如df2,其中包含我想要限制轨迹的城市特定区域的所有坐标:
lat lon
0 40.711 -70.000
1 40.734 -70.099
2 40.740 -70.110
3 40.750 -70.120
我希望将df1中每条轨迹的第一个点和最后一个点与df2中的坐标相匹配,如果第一个点或最后一个点与df2中的任何坐标对匹配,我我只想保留这些轨迹。
(正如我所提到的,我想只保留在城市中结束和开始的轨迹,所以在df1中的“行0-2”的情况下,我想要匹配第0行的lat和lon(起始点)和df2的第2行(轨迹的终点),对于“4-7行”,我会匹配第4行的lat和lon(起始点)然后匹配第7行(结束点),依此类推整个df)
如果我只需要搜索特定“lat”和“lon”的行,也许我可以找到解决方案,如下面的代码所示:
mask = ((df["lat"].isin(df2["lat"])) && (df["lon"].isin(df2["lon"])))
new_df = pd.DataFrame(df[mask])
new_df.head()
但我必须查询每个轨迹的起点和终点,它们以0分隔。我不知道如何做到这一点。
我希望问题很清楚,如果有什么不清楚,请告诉我。
任何帮助都将不胜感激。
答案 0 :(得分:2)
考虑以下输入DataFrame:
In [158]: df
Out[158]:
id1 id2 lat lon
0 1 2 18.46290 -66.10301
1 1 2 37.54900 -71.47700
2 1 2 41.49000 -71.32600
3 0 0 0.00000 0.00000
4 1 3 42.05800 -70.57700 # matching point
5 1 3 42.40200 -70.64200
6 1 3 41.58900 -71.28100
7 1 3 37.64900 -71.44000
8 0 0 0.00000 0.00000
9 2 2 18.46200 -66.10300
10 2 2 18.44857 -66.08900
11 2 2 42.24200 -70.97000 # matching point
12 0 0 0.00000 0.00000
In [159]: df2
Out[159]:
lat lon
0 40.711 -70.000
1 40.734 -70.099
2 40.740 -70.110
3 40.750 -70.120
4 42.058 -70.577 # matching point
5 42.242 -70.970 # matching point
让我们找到所有轨迹的起点和终点的索引:
In [164]: idx = df.loc[(df.id1!=0) & (df.id2!=0)] \
...: .groupby(['id1','id2'])['lat','lon'] \
...: .apply(lambda x: pd.Series([x.index[0], x.index[-1]])) \
...: .stack() \
...: .values
...:
In [165]: idx
Out[165]: array([ 0, 2, 4, 7, 9, 11], dtype=int64)
让我们将坐标乘以100并将它们截断为整数(因为比较Python / Pandas中的浮点数是“邪恶的”):
df2 = df2.mul(100).astype(int)
# `d` - will contain only starting and ending points for each trajectory
d = df.loc[idx]
d.loc[:, ['lat','lon']] = d[['lat','lon']].mul(100).astype(int)
现在我们将所有坐标都整数:
In [181]: d
Out[181]:
id1 id2 lat lon
0 1 2 1846 -6610
2 1 2 4149 -7132
4 1 3 4205 -7057
7 1 3 3764 -7144
9 2 2 1846 -6610
11 2 2 4224 -7097
In [163]: df2
Out[163]:
lat lon
0 4071 -7000
1 4073 -7009
2 4074 -7011
3 4075 -7012
4 4205 -7057
5 4224 -7097
所以我们可以轻松合并它们:
In [185]: d.merge(df2)
Out[185]:
id1 id2 lat lon
0 1 3 4205 -7057
1 2 2 4224 -7097
并将其与原始DF合并:
In [186]: d.merge(df2)[['id1','id2']].merge(df)
Out[186]:
id1 id2 lat lon
0 1 3 42.05800 -70.577
1 1 3 42.40200 -70.642
2 1 3 41.58900 -71.281
3 1 3 37.64900 -71.440
4 2 2 18.46200 -66.103
5 2 2 18.44857 -66.089
6 2 2 42.24200 -70.970