PySpark按最接近的时间值连接两个数据帧

时间:2016-11-16 12:24:09

标签: python-2.7 join pyspark spark-dataframe

我有两个数据框(tx_df和login_df)。 第一个包含player_id,tx_id和tx_time列,而第二个包含player_id和login_time。

我想要做的是使用player_id列加入这两个数据框,但除此之外,还要加入login_df中的最新登录行。 例如,如果有这样的tx_df:

pid_1, txid_1, '2016-11-16 00:01:00'
pid_1, txid_2, '2016-11-16 00:01:02'
pid_1, txid_3, '2016-11-16 00:02:15'
pid_1, txid_4, '2016-11-16 00:02:16'
pid_1, txid_5, '2016-11-16 00:02:17'

和login_df像这样:

pid_1, '2016-11-16 00:02:10'
pid_1, '2016-11-16 00:00:55'
pid_1, '2016-11-13 00:03:00'
pid_1, '2016-11-10 16:30:00'

我希望结果数据框看起来像这样:

pid_1, txid_1, '2016-11-16 00:01:00', pid_1, '2016-11-16 00:00:55'
pid_1, txid_2, '2016-11-16 00:01:02', pid_1, '2016-11-16 00:00:55'
pid_1, txid_3, '2016-11-16 00:02:15', pid_1, '2016-11-16 00:02:10'
pid_1, txid_4, '2016-11-16 00:02:16', pid_1, '2016-11-16 00:02:10'
pid_1, txid_5, '2016-11-16 00:02:17', pid_1, '2016-11-16 00:02:10'

我不是必须绑定到数据框架,所以我们将非常感谢如何使用RDD或任何其他方法很好地完成它。

数据爆炸是我所担心的,因为tx_df可以为每个玩家ID(以及数千名玩家ID)拥有数千个交易条目,而login_df也可以拥有未知数量的玩家登录信息。简单地将这两个加入player_id会因笛卡尔积而产生巨大的数据框架,这是不可接受的。

注意:我正在使用Python API for Spark。

1 个答案:

答案 0 :(得分:0)

为了将来参考,我设法用稍微不同的方法来解决这个问题。 我很幸运,第二个数据框足够小,可以播放它。更准确地说,我播放了值的哈希映射,但这只是因为我发现它很适合这个目的。 (见:broadcast variables in Spark

然后,我迭代了第一个数据帧的行,就像这样

tx_df.rdd.map(my_map_function)

在my_map_function中,我访问了广播的hasmap,确实需要排序和其他操作,最后选择了我想要附加到第一个数据帧的行的值。

作为一个很好的副作用,广播值的散列图,我能够删除数据帧的连接并加快速度。 在此之前,脚本已经

  • 将数据加载到数据框中
  • 将数据框连接成一个
  • 过滤掉不需要的大数据帧行

在此广播解决方案之后,脚本已

  • 将数据加载到数据框中
  • 广播第二个值
  • 仅迭代第一个,直接访问第二个的值并将它们附加到当前行

第二种方法不需要过滤,因为已经选择了正确的值,因此脚本执行速度更快。