2017-10-12 171 views
1

我試圖檢查一個數據框中的每組點之間的笛卡爾距離,以在另一個數據框中分散點的集合,以查看輸入是否超出了我的檢查點的「距離」的閾值。我有這個嵌套循環工作,但是很痛苦(對於40k輸入行約7分鐘,每個檢查vs〜180個其他行,+一些間接操作)。 ''對於df1中的每一對點(a,b),如果從df2到任意點(d,e)的距離>閾值,則打印「是」進入df1.c,在輸入點旁邊。如何在pandas(python)中不通過'for'循環遍歷'嵌套'數據框?

..但我從這得到意想不到的行爲。對於給定的數據,除了一個距離都大於1,但只有df1.1c變得'是'。

感謝您的任何想法 - 這個問題可能是在 'df1.loc ...' 行:

import numpy as np 
from pandas import DataFrame 

inp1 = [{'a':1, 'b':2, 'c':0}, {'a':1,'b':3,'c':0}, {'a':0,'b':3,'c':0}] 
df1 = DataFrame(inp1) 

inp2 = [{'d':2, 'e':0}, {'d':0,'e':3}, {'d':0,'e':4}] 
df2 = DataFrame(inp2) 

threshold = 1 

df1.loc[np.sqrt((df1.a - df2.d) ** 2 + (df1.b - df2.e) ** 2) > threshold, 'c'] = "yes" 

print(df1) 
print(df2) 

    a b c 
0 1 2 yes 
1 1 3 0 
2 0 3 0 

    d e 
0 2 0 
1 0 3 
2 0 4 
+0

這是預期的行爲。正如你所說的「除了一個距離> 1」,這是在C列標記爲「是」的那個。 –

+0

有3x3的距離檢查,所以9箇中有8個> 1。所有輸入行超過dist = 1,所以所有應該得到的是。 – shingdingz

回答

1

這裏是一個想法,以幫助您開始...

來源的DF:

In [170]: df1 
Out[170]: 
    c x y 
0 0 1 2 
1 0 1 3 
2 0 0 3 

In [171]: df2 
Out[171]: 
    x y 
0 2 0 
1 0 3 
2 0 4 

助手DF與笛卡爾乘積:

In [172]: x = df1[['x','y']] \ 
       .reset_index() \ 
       .assign(k=0).merge(df2.assign(k=0).reset_index(), 
            on='k', suffixes=['1','2']) \ 
       .drop('k',1) 


In [173]: x 
Out[173]: 
    index1 x1 y1 index2 x2 y2 
0  0 1 2  0 2 0 
1  0 1 2  1 0 3 
2  0 1 2  2 0 4 
3  1 1 3  0 2 0 
4  1 1 3  1 0 3 
5  1 1 3  2 0 4 
6  2 0 3  0 2 0 
7  2 0 3  1 0 3 
8  2 0 3  2 0 4 

現在我們可以計算距離:

In [169]: x.eval("D=sqrt((x1 - x2)**2 + (y1 - y2)**2)", inplace=False) 
Out[169]: 
    index1 x1 y1 index2 x2 y2   D 
0  0 1 2  0 2 0 2.236068 
1  0 1 2  1 0 3 1.414214 
2  0 1 2  2 0 4 2.236068 
3  1 1 3  0 2 0 3.162278 
4  1 1 3  1 0 3 1.000000 
5  1 1 3  2 0 4 1.414214 
6  2 0 3  0 2 0 3.605551 
7  2 0 3  1 0 3 0.000000 
8  2 0 3  2 0 4 1.000000 

或過濾器:

In [175]: x.query("sqrt((x1 - x2)**2 + (y1 - y2)**2) > @threshold") 
Out[175]: 
    index1 x1 y1 index2 x2 y2 
0  0 1 2  0 2 0 
1  0 1 2  1 0 3 
2  0 1 2  2 0 4 
3  1 1 3  0 2 0 
5  1 1 3  2 0 4 
6  2 0 3  0 2 0 
+0

我有這個工作,謝謝。也許最好還是在幾步之內完成這一切,而不是像我一直在嘗試單線程一樣。一旦我嘗試了真實的數據,它應該會更快。 – shingdingz