Pyspark功能齐全

时间:2017-06-08 20:04:40

标签: apache-spark pyspark

我是Spark的初学者。我正在使用Pyspark将我的遗留Python代码转换为Spark。

我想获得与下面代码相当的Pyspark

usersofinterest = actdataall[actdataall['ORDValue'].isin(orddata['ORDER_ID'].unique())]['User ID']

actdataallorddata都是Spark数据帧。

我不想使用toPandas()函数给出与之相关的缺点。

感谢任何帮助。

3 个答案:

答案 0 :(得分:2)

  • 如果两个数据帧都很大,您应该考虑使用内部联接作为过滤器:

    首先让我们创建一个包含我们要保留的订单ID的数据框:

    orderid_df = orddata.select(orddata.ORDER_ID.alias("ORDValue")).distinct()
    

    现在让我们加入我们的actdataall数据框:

    usersofinterest = actdataall.join(orderid_df, "ORDValue", "inner").select('User ID').distinct()
    
  • 如果您的目标订单ID列表很小,那么您可以使用furianpandit帖子中提到的pyspark.sql isin函数,不要忘记在使用之前广播您的变量(spark会将对象复制到每个节点使他们的任务更快):

    orderid_list = orddata.select('ORDER_ID').distinct().rdd.flatMap(lambda x:x).collect()[0]
    sc.broadcast(orderid_list)
    

答案 1 :(得分:1)

您的代码的最直接翻译将是:

from pyspark.sql import functions as F

# collect all the unique ORDER_IDs to the driver
order_ids = [x.ORDER_ID for x in orddata.select('ORDER_ID').distinct().collect()]

# filter ORDValue column by list of order_ids, then select only User ID column
usersofinterest = actdataall.filter(F.col('ORDValue').isin(order_ids)).select('User ID')

但是,只有当'ORDER_ID'的数量肯定很小(可能<100,000左右)时,才应该像这样过滤。

如果'ORDER_ID'的数量很大,你应该使用一个广播变量,它将order_id列表发送给每个执行者,这样它就可以在本地与order_ids进行比较,以便加快处理速度。请注意,即使'ORDER_ID'很小,这也会有效。

order_ids = [x.ORDER_ID for x in orddata.select('ORDER_ID').distinct().collect()]
order_ids_broadcast = sc.broadcast(order_ids)  # send to broadcast variable
usersofinterest = actdataall.filter(F.col('ORDValue').isin(order_ids_broadcast.value)).select('User ID')

有关广播变量的更多信息,请查看:https://jaceklaskowski.gitbooks.io/mastering-apache-spark/spark-broadcast.html

答案 2 :(得分:0)

所以,你有两个火花数据帧。一个是actdataall,另一个是orddata,然后使用以下命令来获得你想要的结果。

usersofinterest  = actdataall.where(actdataall['ORDValue'].isin(orddata.select('ORDER_ID').distinct().rdd.flatMap(lambda x:x).collect()[0])).select('User ID')
相关问题