使用python

时间:2018-03-08 15:04:31

标签: python pandas shapely geopandas

我有两个数据集,数据集包含经度和纬度值。

让我们说:

  • point_x1是(lang_1,latt_1)
  • point_x2是(lang_2,latt_2)
  
      
  • 第一个数据集有" n" point_x1, x1
  • 的数据行   
  • 第二个数据集有" m" point_x2, x2
  • 的数据行   

其中m> Ñ

修改:注意:m将为20000或更高,n将为5000或更高。

我想分组或合并两个数据集。

我想为每个point_x2找到最近的point_x1 然后 想要为数据集2中的每一行创建一个point_x2, x2, x1(其中point_x1最接近point_x2)的新数据。

数据集1-样品:

-91.850532 40.376043 x1_a1
-91.850519 40.376043 x1_a2
-91.850504 40.376043 x1_a3
-91.850487 40.376043 x1_a4
-91.850399 40.376044 x1_a5
-91.850353 40.376044 x1_a6

dataset2样品:

-91.848442 40.380573 x2_a0
-91.850292 40.378533 x2_a1
-91.849919 40.377883 x2_a2
-91.849109 40.385833 x2_a3
-91.845884 40.381623 x2_a4
-91.847344 40.376693 x2_a5
-91.846937 40.382653 x2_a6
-91.849827 40.381343 x2_a7
-91.850149 40.383474 x2_a8
-91.848569 40.384904 x2_a9
-91.849063 40.377384 x2_a10
-91.845563 40.378604 x2_a11

我对数据科学或地理分析并不了解。寻求方法方面的帮助。

请建议我怎么做。

2 个答案:

答案 0 :(得分:1)

我写了一些示例代码。您可以尝试这样:

from math import radians, cos, sin, asin, sqrt
import pandas as pd

def geo_distance(lng1,lat1,lng2,lat2):
    lng1, lat1, lng2, lat2 = map(radians, [lng1, lat1, lng2, lat2])
    dlon=lng2-lng1
    dlat=lat2-lat1
    a=sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2 
    dis=2*asin(sqrt(a))*6371*1000
    return dis



df1 = pd.DataFrame({'lang_1':[-91.850532,-91.850519,-91.850504,-91.850487,-91.850399,-91.850353],
                    'latt_1':[40.376043,40.376043,40.376043,40.376043,40.376044,40.376044],
                    'x1':['x1_a1','x1_a2','x1_a3','x1_a4','x1_a5','x1_a6']})
df2 = pd.DataFrame({'lang_2':[-91.848442,-91.850292,-91.849919,-91.849109,-91.845884,-91.847344,-91.846937,-91.849827,-91.850149,-91.848569,-91.849063,-91.845563],
                    'latt_2':[40.380573,40.378533,40.377883,40.385833,40.381623,40.376693,40.382653,40.381343,40.383474,40.384904,40.377384,40.378604],
                    'x2':['x2_a0','x2_a1','x2_a2','x2_a3','x2_a4','x2_a5','x2_a6','x2_a7','x2_a8','x2_a9','x2_a10','x2_a11']})

df1['key']=0
df2['key']=0

df_cartesian = df2.merge(df1, how='outer')
df_cartesian['geo_distance']=df_cartesian.apply(lambda row:geo_distance(row['lang_1'],row['latt_1'],row['lang_2'],row['latt_2']),axis=1)
df_cartesian_min_distance=df_cartesian.sort_values(by="geo_distance").groupby(["lang_2","latt_2","x2"],as_index=False).first()
print(df_cartesian_min_distance.ix[:,["lang_2","latt_2","x2","x1"]])

答案 1 :(得分:1)

我不确定它是否有用,但我提出了比威廉更紧凑的版本:

import pandas

dataset1 = pandas.DataFrame(data={'x':(-91.850532, -91.850519, -91.850504, -91.850487, -91.850399, -91.850353),
                                  'y':(40.376043, 40.376043,  0.376043, 40.376043, 40.376044, 40.376044)},
                            index=('x1_a1', 'x1_a2', 'x1_a3', 'x1_a4', 'x1_a5', 'x1_a6'))


dataset2 = pandas.DataFrame(data={'x':(-91.848442, -91.850292, -91.849919, -91.849109, -91.845884, -91.847344, -91.846937, -91.849827, -91.850149, -91.848569, -91.849063, -91.845563),
                                  'y':(40.380573, 40.378533, 40.377883, 40.385833, 40.381623, 40.376693, 40.382653, 40.381343, 40.383474, 40.384904, 40.377384, 40.378604)},
                            index=('x2_a0', 'x2_a1', 'x2_a2', 'x2_a3', 'x2_a4', 'x2_a5', 'x2_a6', 'x2_a7', 'x2_a8', 'x2_a9', 'x2_a10', 'x2_a11'))

closest_points = {}
for name, point in dataset1.iterrows():
    distances = (((dataset2 - point) ** 2).sum(axis=1)**.5)
    closest_points[name] = distances.sort_values().index[0]

在两组点之间采用简单的欧几里得,并且对于dataset1中的每个点,获取最接近它的数据集2中的点的名称。我相信你可以从这里轻松地调整它以满足你的需求。