Bing 地图 - 如何使用数据框在 pyspark 中使用路线 api

Bing map - How to use route api in pyspark using dataframe

我正在尝试通过传递来自数据框列的纬度、经度坐标来使用 Bing 路线 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

当我调用 bing_maps 而不使用 udf

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

非常感谢您的帮助

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

您的 bing_maps 函数将调用 ''.join([x_lat, ',', x_long]),,它默认假定可迭代对象(在本例中为列表)的参数都是字符串。这就是手动调用它(不使用用户定义函数 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),

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

所以我只更改了这条语句并且它起作用了:

udfbing = udf(bing_maps, StringType())