2017-10-02 12 views
1

それぞれ緯度と経度のデータを含む2つのデータフレームdf1df2があります。 df1の観測ごとに、haversine関数を使用して、各点間の距離をdf2に計算したいと考えています。私は2つのアプローチを試しましたが、大規模なデータセットではパフォーマンスが問題になります。2つのデータフレーム間のHaversine距離の計算

In [1]: import pandas as pd 
     import numpy as np 
     from haversine import haversine 

In [2]: df1 = pd.DataFrame({'lat_long': [(25.99550273, 179.18526021), (76.24387873, -34.21956936), (-51.43773064, -113.93795667)]}) 
     df2 = pd.DataFrame({'lat_long': [(22.89956242, 107.04009984), (-80.25375578, -92.05425401), (-0.81621289, -147.26962084), (0,0)]}) 

In [3]: # method 1: iterate through rows 
     for i in df1['lat_long']: 
      for j in df2['lat_long']: 
       print(haversine(i,j)) 

7215.01729234 
12830.1178484 
4673.37638582 
17123.1981646 
8678.49300206 
17721.004245 
10690.0998826 
8746.62635254 
15294.1258757 
3303.30690512 
6434.34272913 
11636.6462421 

In [4]: # method 2: create one dataframe and then perform calculation 
     df1_dup = df1.append([df1]*(len(df2)-1), ignore_index=True) 
     df2_dup = df2.append([df2]*(len(df1)-1), ignore_index=True) 
     df = pd.DataFrame({'lat_long_df1': df1_dup.sort_values('lat_long')['lat_long'],'lat_long_df2': df2_dup['lat_long']}) 
     print(df.apply(lambda x: haversine(x['lat_long_df1'], x['lat_long_df2']), axis=1)) 

0  7215.017292 
1  17721.004245 
2  6434.342729 
3  17123.198165 
4  8678.493002 
5  3303.306905 
6  4673.376386 
7  8746.626353 
8  15294.125876 
9  12830.117848 
10 10690.099883 
11 11636.646242 
dtype: float64 

はるかに大きなデータフレームでうまくいく代替アプローチのアイデアはありますか?

+0

「df1」の各ポイントと「df2」の各ポイントの距離を計算しますか? a.k.a.「df1」の要素と「df2」の要素との間に距離を対で計算するか?距離は厳密にする必要がありますか、少なくともいくつかの要素についてはhaversineよりも簡単な式で逃げることができますか?あなたは本当にすべてのペアを処理する必要がありますか?基本的には、より洗練された構文でこれを行うことはできますが、計算の一部を何とかスキップすることができない限り、パフォーマンスを大幅に改善するものはありません。 –

+2

これは関連する質問です:https://stackoverflow.com/questions/29545704/fast-haversine-approximation-python-pandas –

+0

@DavidZはい、私は対の距離が必要です。パフォーマンスが大幅に向上した場合、距離の精度を犠牲にする可能性があります。 –

答えて

1

あなたはよりパフォーマンスマージを探しているなら、あなたはクロス代理列に参加することが可能です。

temp = df1.assign(A=1).merge(df2.assign(A=1), on='A').drop('A', 1) 
temp 
         lat_long_x     lat_long_y 
0  (25.99550273, 179.18526021) (22.89956242, 107.04009984) 
1  (25.99550273, 179.18526021) (-80.25375578, -92.05425401) 
2  (25.99550273, 179.18526021) (-0.81621289, -147.26962084) 
3  (25.99550273, 179.18526021)      (0, 0) 
4  (76.24387873, -34.21956936) (22.89956242, 107.04009984) 
5  (76.24387873, -34.21956936) (-80.25375578, -92.05425401) 
6  (76.24387873, -34.21956936) (-0.81621289, -147.26962084) 
7  (76.24387873, -34.21956936)      (0, 0) 
8 (-51.43773064, -113.93795667) (22.89956242, 107.04009984) 
9 (-51.43773064, -113.93795667) (-80.25375578, -92.05425401) 
10 (-51.43773064, -113.93795667) (-0.81621289, -147.26962084) 
11 (-51.43773064, -113.93795667)      (0, 0) 

temp.apply(lambda x: haversine(x['lat_long_x'], x['lat_long_y']), 1) 
0  7215.017292 
1  12830.117848 
2  4673.376386 
3  17123.198165 
4  8678.493002 
5  17721.004245 
6  10690.099883 
7  8746.626353 
8  15294.125876 
9  3303.306905 
10  6434.342729 
11 11636.646242 
dtype: float64 

あなたは素敵な速度向上のためにthis questionからの回答とパフォーマンスのマージを組み合わせることができます。また、緯度/経度のデータを別々の列に保存することを検討する必要があります。

関連する問題