比较PySpark中地理空间数据的最有效方法

时间:2016-11-01 17:40:16

标签: python-2.7 pyspark geospatial

我知道在常规Python shell中我们可以使用pyproj例如

from pyproj import Geod
nyc_geod = Geod(ellps='WGS84')
lat1, lon1 = (70, -74)
lat2, lon2 = (71, -72)
z1,z2,dist = nyc_geod.inv(lon1,lat1,lon2,lat2)
dist --> 134163.09514455328

然后我可以打电话给dist给我两点之间的距离。 PySpark中是否有这样的功能,特别是因为它与比较两个DataFrame之间的点有关?感谢

1 个答案:

答案 0 :(得分:2)

从稍微重新编写代码开始,以便有一个距离函数

from pyproj import Geod
import numpy as np
import pandas as pd

nyc_geod = Geod(ellps='WGS84')
def calc_nyc_geod(lon1,lat1,lon2,lat2):
  _, _ ,dist = nyc_geod.inv(lon1,lat1,lon2,lat2)
  return dist
# show a single point
lat1, lon1 = (70, -74)
lat2, lon2 = (71, -72)
print(calc_nyc_geod(lon1,lat1,lon2,lat2))

你可以制作两个随机的DataFrame(这里有numpy和pandas,但它们可以来自任何来源)

np.random.seed(1234)
df1 = sqlContext.createDataFrame(pd.DataFrame({'lat': np.random.uniform(lat1, lat2, 10),
                    'lon': np.random.uniform(lon1, lon2, 10),
                   }))
df2 = sqlContext.createDataFrame(pd.DataFrame({'lat': np.random.uniform(lat1, lat2, 10),
                    'lon': np.random.uniform(lon1, lon2, 10),
                   }))

很难从您的问题中看出,但听起来目标是加入两个不同的DataFrame并使用距离指标作为标准。对于这种情况,df1中的多少点在df2的35000米(?)范围内(注意:这是一个完整的外部连接,如果您已经了解了有关数据的信息,则可以使用更智能的连接)。 为此,您需要在UserDefinedFunction对象内部生成SQLContext,并且因为输入了DataFrame,所以也必须输入输出。

from pyspark.sql.types import DoubleType
sqlContext.registerFunction("nyc_geod", calc_nyc_geod, DoubleType())
df1.registerTempTable("TDF1")
df2.registerTempTable("TDF2")
sqlContext.sql("""
SELECT COUNT(*) as Overlap FROM TDF1 
JOIN TDF2 
WHERE nyc_geod(TDF1.lon, TDF1.lat, TDF2.lon, TDF2.lat)<35000
""").first()

结果是Row(Overlap=38)符合条件的点对数(100)。