2017-04-16 121 views
1

我處理以下數據幀:如何篩選熊貓數據框?

 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 )。

也許我可以在下面的代碼已經找到了解決辦法,如果我必須只搜索具有特定的「緯度」和「經度」行,如:

 mask = ((df["lat"].isin(df2["lat"])) && (df["lon"].isin(df2["lon"]))) 
     new_df = pd.DataFrame(df[mask]) 
     new_df.head() 

但我要查詢的起始和以0分隔的每個軌跡的終點。我不知道該怎麼做。

我希望問題很清楚,如果有什麼不清楚的地方請告訴我。

任何幫助,將不勝感激。

+0

是否'df2' DF確實含有__all__城市特定區域的座標 - 有沒有可能?這些座標有多精確? – MaxU

+0

@MaxU不,df2只是爲了說明。 – Liza

+0

我問你的真實數據......考慮這個例子:你有第一個座標爲'(40.7111,-70.0001)'的軌跡點,在'df2'中有'(40.711,-70.000) - 他們__不會匹配 – MaxU

回答

2

考慮下面的輸入DataFrames:

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 /熊貓是「邪惡」):

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 
+0

謝謝sooo,這幾乎是我想要的,但最後,輸出df應該有點不同。輸出df只包含那些匹配的點,我想要整個軌跡,就像df1中第4行的匹配一樣,這意味着軌跡從我們指定的區域開始,現在**最終的df **應該包含從第4行到第7行的所有點,然後是第9行到第11行,因爲它在第11行有匹配。 – Liza

+0

@Liza,我已經更新了答案 - 請檢查 – MaxU

+0

這是完美的,謝謝sooooooo了。 – Liza