簡體   English   中英

如何過濾熊貓數據框?

[英]How to filter pandas data frame?

我正在處理以下數據框:

      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 

以上數據是軌跡數據,我想找到所有以城市為起點或終點的軌跡。

每個軌跡具有多個點,並且這些軌跡由上述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行(起點)和第2行的經緯度(軌跡的終點)與df2對應,對於“第4-7行”,我將匹配第4行(起點)的經緯度,然后匹配第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隔開。 我不知道該怎么做。

我希望這個問題是明確的,讓我知道是否有任何不清楚的地方。

任何幫助,將不勝感激。

考慮以下輸入數據幀:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM