Pyspark根据距离加入两张桌子

时间:2018-06-18 03:41:33

标签: pyspark pyspark-sql

我有两张表storeweather_station。从特定的商店中找到关闭气象站并创建一个包含此详细信息的新表我正在使用以下代码。

def closest(weather_station, store):
    return min(weather_station, key=lambda p: distance(store['lat'], store['lon'], p['lat'], p['lon']))

for store in store_details:
    print store
    print closest(weather_station_details, store)

它没有任何问题。如果我运行这个样本数据,我会得到正确的结果。

weather_station_details=[
    {'date': '2018-03-06T13:00:00.000Z', 'station_cd': 'CYGK', 'station_nm': 'Kingston', 'lat': 44.22587, 'lon': -76.5966},
    {'date': '2018-03-06T13:00:00.000Z', 'station_cd': 'CXOA', 'station_nm': 'OTTAWA CDA RCS', 'lat': 45.383333, 'lon': -75.716667},
    {'date': '2018-03-06T13:00:00.000Z', 'station_cd': 'CYUL', 'station_nm': 'Montreal/Trudeau International', 'lat': 45.47046, 'lon': -73.74093},
    {'date': '2018-03-06T13:00:00.000Z', 'station_cd': 'CYYC', 'station_nm': 'Calgary International', 'lat': 51.12262, 'lon': -114.01335},
    {'date': '2018-03-06T12:00:00.000Z', 'station_cd': 'CPEA', 'station_nm': 'EDGERTON AGCM', 'lat': 52.783333, 'lon': -110.433333},
    {'date': '2018-03-06T12:00:00.000Z', 'station_cd': 'CPEH', 'station_nm': 'ENCHANT AGDM', 'lat': 50.183333, 'lon': -112.433333},
    {'date': '2018-03-06T12:00:00.000Z', 'station_cd': 'CPGE', 'station_nm': 'GILT EDGE NORTH AGCM', 'lat': 53.066667, 'lon': -110.616667},
    {'date': '2018-03-06T12:00:00.000Z', 'station_cd': 'CPHU', 'station_nm': 'HUGHENDEN AGCM AB', 'lat': 52.583333, 'lon': -110.783333},
    {'date': '2018-03-06T12:00:00.000Z', 'station_cd': 'CPIR', 'station_nm': 'IRON SPRINGS AGDM', 'lat': 49.9, 'lon': -112.733333},
]

store_details=[
    {'lon': -113.99361, 'store_num': 'A111', 'lat': 51.201838},
    {'lon': -73.792339, 'store_num': 'A222', 'lat': 45.53343},
    {'lon': -75.699475, 'store_num': 'A333', 'lat': 45.475785},
    {'lon': -76.564509, 'store_num': 'A444', 'lat': 44.244361},
]

然而,由于数据量很大并且为了获得性能,我尝试使用pyspark。但是我被卡住了。我不能将一个数据帧作为参数传递给函数,或者不能使它成为全局的。

无论如何我可以在pyspark实现这个目标吗?

1 个答案:

答案 0 :(得分:0)

至少有几种方法可以做到这一点。我这里只提供大纲。

一种方法:

  1. 定义UDF distance以计算任意商店和气象站对之间的距离。
  2. 使用stores数据框执行weather_stations数据框的笛卡尔联接。如果其中一个数据帧很小(几MB),则可以强制它为广播连接。 (警告:这将导致数据框的大小为M x N,其中M和N是两个原始数据框的大小。这可能会轻易炸毁您的可用存储空间。)
  3. 使用UDF计算每个商店/电台对之间的距离。
  4. 按商店分组或使用商店分区的窗口功能选择距离最小的气象站。
  5. 另一种方法:

    1. 定义一个UDF min_distance,它占用商店并找到距离最小的气象站。同样,如果气象站列表相当小,那么广播气象站数据结构以加快这一步骤是合适的。
    2. 将此UDF应用于stores数据框。