我遇到以下问题: 我有一个列表,我需要与数据框(acc_name)中的列元素进行比较。我使用以下循环函数但它只返回1条记录,它应该提供给我30。 使用Pyspark
bs_list =
['AC_E11','AC_E12','AC_E13','AC_E135','AC_E14','AC_E15','AC_E155','AC_E157',
'AC_E16','AC_E163','AC_E165','AC_E17','AC_E175','AC_E180','AC_E185', 'AC_E215','AC_E22','AC_E225','AC_E23','AC_E23112','AC_E235','AC_E245','AC_E258','AC_E25','AC_E26','AC_E265','AC_E27','AC_E275','AC_E31','AC_E39','AC_E29']
for i in bs_list:
bs_acc1 = (acc\
.filter(i == acc.acc_name)
.select(acc.acc_name,acc.acc_description)
)
bs_list元素是acc_name列的子集。我正在尝试创建一个新的DF,它将包含以下2列acc_name,acc_description。它仅包含列表bs_list中存在的元素值的详细信息 请告诉我哪里出错了?
答案 0 :(得分:0)
那是因为,每当你在i
上过滤时,你都会在循环中创建一个新的数据帧bs_acc1。所以它必须只显示属于bs_list中最后一个值的1行,即'AC_E29'
的行
这样做的一种方法是重复与自身结合,因此之前的结果也保留在数据框中,如 -
# create a empty dataframe, give schema which is appropriate to your data below
bs_acc1 = sqlContext.createDataFrame(sc.emptyRDD(), schema)
for i in bs_list:
bs_acc1 = bs_acc1.union(
acc\
.filter(i == acc_fil.acc_name)
.select(acc.acc_name,acc.acc_description)
)
更好的方法是根本不做循环 -
from pyspark.sql.functions import *
bs_acc1 = acc.where(acc.acc_name.isin(bs_list))
答案 1 :(得分:0)
您还可以将bs_list
转换为带有acc_name
列的数据框,然后加入acc
数据框。
bs_rdd = spark.sparkContext.parallelize(bs_list)
bs_df = bs_rdd.map(lambda x: Row(**{'acc_name':x})).toDF()
bs_join_df = bs_df.join(acc, on='acc_name')
bs_join_df.show()