Python 如何从pyspark中的另一列中查找一列的顶级层次结构?
我想找到组织中员工的顶层层次结构,并使用pyspark分配报告级别 我们已经使用spark GraphX通过Scala支持解决了这个问题。我们希望在python中这样做,但不使用GraphFrame(DFs优先选择)。是否可以使用spark DFs进行此操作?如果没有,那我们就去买笔架 共有两个DFs,即员工和所需的层次结构Python 如何从pyspark中的另一列中查找一列的顶级层次结构?,python,apache-spark,pyspark,apache-spark-sql,pyspark-sql,Python,Apache Spark,Pyspark,Apache Spark Sql,Pyspark Sql,我想找到组织中员工的顶层层次结构,并使用pyspark分配报告级别 我们已经使用spark GraphX通过Scala支持解决了这个问题。我们希望在python中这样做,但不使用GraphFrame(DFs优先选择)。是否可以使用spark DFs进行此操作?如果没有,那我们就去买笔架 共有两个DFs,即员工和所需的层次结构 employee_df包含组织中所有员工的所有信息 required_hierarchy_df包含我们需要为其找到组织中最高层级的员工 请参考以下示例: 所需的层次结构:
employee_id | designation | supervisor_id | supervisor_designation
10 | Developer | 05 | Techincal Lead
雇员身份证:
employee_id | designation | supervisor_id | supervisor_designation
10 | Developer | 05 | Techincal Lead
05 | Technical Lead | 04 | Manager
04 | Director | 03 | Sr. Director
03 | Sr. Director| 02 | Chairman
02 | Chairman | 01 | CEO
01 | CEO | null | null
预期产出:
员工的报告级别:
报告级别(df):
employee_id | level_1_id | level_2_id | level_3_id | level_4_id | level_5_id
10 | 05 | 04 | 03 | 02 | 01
employee_id | designation | top_level_id | top_level_designation
10 | Developer | 01 | CEO
组织中的顶级层次结构信息:
顶层设计图:
employee_id | level_1_id | level_2_id | level_3_id | level_4_id | level_5_id
10 | 05 | 04 | 03 | 02 | 01
employee_id | designation | top_level_id | top_level_designation
10 | Developer | 01 | CEO
考虑不使用spark作为其仅有的200万行。使用类似于dict-/graph-/tree的数据结构使这变得非常简单。我建议不要使用Spark数据帧执行此操作 使用Spark DataFrames,您可以通过递归连接来解决这个问题,创建dataframe
报告\u level\u df
。这不是一个好的和/或有效的解决方案
代码
我们对员工与主管的关系感兴趣
edges = employee_df.select('employee_id', 'supervisor_id')
可以说,向上迈出一步需要一次连接
level_0 = edges \
.withColumnRenamed('employee_id', 'level_0') \
.withColumnRenamed('supervisor_id', 'level_1')
level_1 = edges \
.withColumnRenamed('employee_id', 'level_1') \
.withColumnRenamed('supervisor_id', 'level_2')
# Join, sort columns and show
level_0 \
.join(level_1, on='level_1') \
.select('level_0', 'level_1', 'level_2') \
.show()
我们希望递归地遍历它们
total = edges \
.withColumnRenamed('employee_id', 'level_0') \
.withColumnRenamed('supervisor_id', 'level_1')
levels = 10
for i in range(1, levels):
level_i = edges \
.withColumnRenamed('employee_id', 'level_{}'.format(i)) \
.withColumnRenamed('supervisor_id', 'level_{}'.format(i+1))
total = total \
.join(level_i, on='level_{}'.format(i), how='left')
# Sort columns and show
total \
.select(['level_{}'.format(i) for i in range(levels)]) \
.show()
除了我们不想猜测层数,所以我们每次都检查是否已经完成。这需要运行所有数据,因此速度较慢
schema = 'employee_id int, supervisor_id int'
edges = spark.createDataFrame([[10, 5], [5, 4], [4, 3], [3, 2], [2, 1], [1, None]], schema=schema)
total = edges \
.withColumnRenamed('employee_id', 'level_0') \
.withColumnRenamed('supervisor_id', 'level_1')
i = 1
while True:
this_level = 'level_{}'.format(i)
next_level = 'level_{}'.format(i+1)
level_i = edges \
.withColumnRenamed('employee_id', this_level) \
.withColumnRenamed('supervisor_id', next_level)
total = total \
.join(level_i, on=this_level, how='left')
if total.where(f.col(next_level).isNotNull()).count() == 0:
break
else:
i += 1
# Sort columns and show
total \
.select(['level_{}'.format(i) for i in range(i+2)]) \
.show()
结果
+-------+-------+-------+-------+-------+-------+-------+
|level_5|level_4|level_3|level_2|level_1|level_0|level_6|
+-------+-------+-------+-------+-------+-------+-------+
| null| null| null| null| null| 1| null|
| null| null| null| null| 1| 2| null|
| null| null| null| 1| 2| 3| null|
| null| null| 1| 2| 3| 4| null|
| null| 1| 2| 3| 4| 5| null|
| 1| 2| 3| 4| 5| 10| null|
+-------+-------+-------+-------+-------+-------+-------+
您只需要
employee_df
就可以完成这项任务,对吗?对于每个employee\u id
查找“最高”(最低数量)的链式主管?在employee\u df
中(可能)有多少行?Hi@LaurensKoppenol。。对不起,回信晚了。1) 是的,我们只需要employee_df
就可以完成这项工作。对,这就像是链式的层次结构。首先要在所需的层次结构\u df
和员工\u df
-->之间找到匹配的员工ID,其次要不断搜索主管ID,直到它没有“null”(表示他是该组织中员工的头号人物)。因此,在我举的employee_id=10(开发者)的例子中,该组织的头号人物是employee_id=01(CEO)。employee_df文件中大约有两百万条记录,但如果有逻辑,我将在稍后查找性能问题或挑战。但现在我们没有任何逻辑来实现这一点。非常感谢Laurens Koppenol的解决方案。这对我来说很有效:-)