2017-04-17 215 views
3

我想計算GPS座標路徑上的距離,這些座標存儲在數據幀的兩列中。熊貓數據幀連續行之間重複計算

import pandas as pd 

df = pd.DataFrame({ 'lat' : [1, 2.5, 3, 1.2], 
        'lng' : [1, 1, 2.1, 1], 
        'label': ['foo', 'bar', 'zip', 'foo']}) 
print df 

輸出

label lat lng 
0 foo 1.0 1.0 
1 bar 2.5 1.0 
2 zip 3.0 2.1 
3 foo 1.2 1.0 

的GPS座標存儲在弧度。

import math as m 

r1 = 0 
r2 = 1 

distance =m.acos(m.sin(df.lat[r1]) * m.sin(df.lat[r2]) + 
    m.cos(df.lat[r1]) * m.cos(df.lat[r2]) * m.cos(df.lng[r2]-df.lng[r1]))*6371 

我想重複每對連續行之間的這種計算,然後添加每一個短距離進入較長的最終距離:因此,可以如下計算出的數據幀的第一和第二行之間的距離爲完整的路徑。

我可以把它放到數據幀的n-1行的循環中,但是有沒有更多pythonic的方法來做到這一點?

回答

6

矢量化Haversine功能:

def haversine(lat1, lon1, lat2, lon2, to_radians=True, earth_radius=6371): 
    """ 
    slightly modified version: of http://stackoverflow.com/a/29546836/2901002 

    Calculate the great circle distance between two points 
    on the earth (specified in decimal degrees or in radians) 

    All (lat, lon) coordinates must have numeric dtypes and be of equal length. 

    """ 
    if to_radians: 
     lat1, lon1, lat2, lon2 = np.radians([lat1, lon1, lat2, lon2]) 

    a = np.sin((lat2-lat1)/2.0)**2 + \ 
     np.cos(lat1) * np.cos(lat2) * np.sin((lon2-lon1)/2.0)**2 

    return earth_radius * 2 * np.arcsin(np.sqrt(a)) 

解決方案:

df['dist'] = haversine(df['lat'], df['lng'], 
         df['lat'].shift(), df['lng'].shift(), 
         to_radians=False) 

結果:

In [65]: df 
Out[65]: 
    label lat lng   dist 
0 foo 1.0 1.0   NaN 
1 bar 2.5 1.0 9556.500000 
2 zip 3.0 2.1 7074.983158 
3 foo 1.2 1.0 10206.286067 
+0

謝謝,半正矢函數工作,當我輸入號碼LAT1,lon1等,但當我在我的實際數據框上嘗試時,它會返回錯誤:'AttributeError:'float'object has no attribute'sin' '。我可以從循環打印'np.sin(dlat/2.0)** 2',沒有任何問題。關於如何解決這個問題的任何想法? –

+0

@omomo,確保你沒有名爲'np'的變量,並且你沒有錯別字......還要確保你至少傳遞了四個參數到''lat1,lon1,lat2,lon2 ' – MaxU

+0

有沒有辦法在堆棧溢出時共享一個數據幀,可能是.pkl文件?當我用數字從頭開始創建數據框時,它可以工作。但是我使用的是從excel文件導入數據的實際數據框。 excel數據框和從頭開始構建的數據框看起來都是一樣的,dtypes是相同的,我無法弄清楚有什麼不同。 –