Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何从pyspark中的另一列中查找一列的顶级层次结构?_Python_Apache Spark_Pyspark_Apache Spark Sql_Pyspark Sql - Fatal编程技术网

Python 如何从pyspark中的另一列中查找一列的顶级层次结构?

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包含我们需要为其找到组织中最高层级的员工 请参考以下示例: 所需的层次结构:

我想找到组织中员工的顶层层次结构,并使用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的解决方案。这对我来说很有效:-)