Bing map - 如何使用dataframe在pyspark中使用route api

时间:2017-11-21 04:52:01

标签: pyspark bing-maps pyspark-sql

我试图通过传递来自dataframe列的纬度,经度坐标来计算使用Bing Route API的旅行时间。我的代码如下所示:

def bing_maps(x_lat, x_long, y_lat, y_long):
    try:
        par = {
            'wp.0': ''.join([x_lat, ',', x_long]),
            'wp.1': ''.join([y_lat, ',', y_long]),
            'avoid': 'minimizeTolls',
            'key' : CMEConfig.bingKey } 
        return requests.get(CMEConfig.bingURL, par).json()['resourceSets'][0]['resources'][0]['travelDuration']

    except:
        return 'no_location_available'

udfbing = udf(bing_maps, IntegerType())  

PostalCodeMatrixDistance3 = PostalCodeMatrixDistance2\
    .withColumn('driving_time', udfbing('FromLatitude', 'FromLongitude', 'ToLatitude', 'ToLongitude'))

驾驶时间是在功能中计算的,但似乎不想将其交给并放入“driving_time”栏。我怀疑它与数据类型有关,但我无法弄明白。

手动调用该函数时,似乎可以正常工作,参见示例:

def bing_maps(x_lat, x_long, y_lat, y_long):
    try:
        par = {
            'wp.0': ''.join([x_lat, ',', x_long]),
            'wp.1': ''.join([y_lat, ',', y_long]),
            'avoid': 'minimizeTolls',
            'key' : CMEConfig.bingKey } 
        res = requests.get(CMEConfig.bingURL, par).json()['resourceSets'][0]['resources'][0]['travelDuration']
        print(res)
        return res
    except:
        return 'no_location_available'

bing_maps('42.843', '-2.6748', '42.6667', '-2.4591')

我回来的答案是

2742

当我在不使用udf

的情况下调用bing_maps时
PostalCodeMatrixDistance3 = PostalCodeMatrixDistance2\
    .withColumn('driving_time', bing_maps('FromLatitude', 'FromLongitude', 'ToLatitude', 'ToLongitude'))

我得到这个错误:

col should be Column
Traceback (most recent call last):
  File "/usr/hdp/current/spark2-client/python/pyspark/sql/dataframe.py", line 1501, in withColumn
    assert isinstance(col, Column), "col should be Column"
AssertionError: col should be Column

非常感谢您的帮助

2 个答案:

答案 0 :(得分:1)

我已经复制了您的代码,它似乎工作正常,这让我相信错误与数据框的数据类型有关。

您的bing_maps函数将调用''.join([x_lat, ',', x_long]),,它默认假定iterable的参数(本例中的列表)都是字符串。这就是为什么手动调用它(不使用用户定义的函数,udf)的原因。

如果您的数据框中的'FromLatitude', 'FromLongitude', 'ToLatitude', 'ToLongitude'列不属于StringType,而是DoubleType,然后调用udfbing将导致Python TypeError TypeError: sequence item 0: expected str instance, float found

解决这个问题的一种方法(同时允许转换为字符串的浮点数)是改变数据连接的方式。考虑例如改变

'wp.0': ''.join([x_lat, ',', x_long]),

'wp.0': "{lat1},{long1}".format(lat1=x_lat, long1=x_long),

答案 1 :(得分:0)

谢谢奥利弗,你的回答帮助我走上正轨。 这不是导致问题的输入参数,但是我已经按照建议增强了代码,但是作为输出的驱动时间。 我将它定义为整数,但不知何故,数据帧希望它返回为字符串。

所以我只改变了这个陈述并且有效:

udfbing = udf(bing_maps, StringType())