Apache spark 为Spark数据帧中的每个组创建索引

Apache spark 为Spark数据帧中的每个组创建索引,apache-spark,apache-spark-sql,Apache Spark,Apache Spark Sql,我在Spark中有一个数据框,有两列,group\u id和value,其中value是双精度的。我想根据组id对数据进行分组,按值对每个组进行排序,然后添加第三列索引,它表示值在组值排序中的位置 例如,考虑以下输入数据: +--------+-----+ |group_id|value| +--------+-----+ |1 |1.3 | |2 |0.8 | |1 |3.4 | |1 |-1.7 | |2 |2.3 | |2

我在Spark中有一个数据框,有两列,
group\u id
value
,其中
value
是双精度的。我想根据
组id
对数据进行分组,按
对每个组进行排序,然后添加第三列
索引
,它表示
在组值排序中的位置

例如,考虑以下输入数据:

+--------+-----+
|group_id|value|
+--------+-----+
|1       |1.3  |
|2       |0.8  |
|1       |3.4  |
|1       |-1.7 |
|2       |2.3  |
|2       |5.9  |
|1       |2.7  |
|1       |0.0  |
+--------+-----+
然后,输出将类似于

+--------+-----+-----+
|group_id|value|index|
+--------+-----+-----+
|1       |-1.7 |1    |
|1       |0.0  |2    |
|1       |1.3  |3    |
|1       |2.7  |4    |
|1       |3.4  |5    |
|2       |0.8  |1    |
|2       |2.3  |2    |
|2       |5.9  |3    |
+--------+-----+-----+
索引是否基于0以及排序是升序还是降序都不重要

作为后续,考虑在原始数据中存在一个第三列“<代码>额外<代码> >的情况,该原始数据对一些<代码>(GROPGID,Value)组合具有多个值。例如:

+--------+-----+-----+
|group_id|value|extra|
+--------+-----+-----+
|1       |1.3  |1    |
|1       |1.3  |2    |
|2       |0.8  |1    |
|1       |3.4  |1    |
|1       |3.4  |2    |
|1       |3.4  |3    |
|1       |-1.7 |1    |
|2       |2.3  |1    |
|2       |5.9  |1    |
|1       |2.7  |1    |
|1       |0.0  |1    |
+--------+-----+-----+
是否有办法添加
索引
列,以便不考虑但仍保留
额外的
列?这种情况下的输出将是

+--------+-----+-----+-----+
|group_id|value|extra|index|
+--------+-----+-----+-----+
|1       |-1.7 |1    |1    |
|1       |0.0  |1    |2    |
|1       |1.3  |1    |3    |
|1       |1.3  |2    |3    |
|1       |2.7  |1    |4    |
|1       |3.4  |1    |5    |
|1       |3.4  |2    |5    |
|1       |3.4  |3    |5    |
|2       |0.8  |1    |1    |
|2       |2.3  |1    |2    |
|2       |5.9  |1    |3    |
+--------+-----+-----+-----+
我知道可以通过复制数据,删除额外的
列来实现这一点

  • 复制数据
  • 删除
    extra
  • 执行
    distinct
    操作,这将导致原始示例中的数据
  • 使用原始解决方案计算
    索引
  • 将结果与第二个示例中的数据连接起来

  • 然而,这将涉及大量额外的计算和开销

    您可以使用
    窗口
    函数根据
    创建排名列,并按
    组id
    分区:

    从pyspark.sql.window导入窗口
    从pyspark.sql.functions导入秩,密集秩
    #定义窗口
    window=window.partitionBy(df['group\u id']).orderBy(df['value']))
    #创建列
    df.select('*',rank().over(window).alias('index')).show()
    +--------+-----+-----+
    |组id |值|索引|
    +--------+-----+-----+
    |       1| -1.7|    1|
    |       1|  0.0|    2|
    |       1|  1.3|    3|
    |       1|  2.7|    4|
    |       1|  3.4|    5|
    |       2|  0.8|    1|
    |       2|  2.3|    2|
    |       2|  5.9|    3|
    +--------+-----+-----+
    
    因为,您首先选择了
    “*”
    ,所以您还可以使用上述代码保留所有其他变量。但是,您的第二个示例显示您正在寻找函数
    densite\u rank()
    ,该函数以列的形式提供,没有空格:

    df.select('*',densite_rank().over(window.alias('index'))
    
    谢谢,这非常有效。我已经添加了一个扩展示例,希望您可以查看。请参见编辑,您可能正在查找
    densed\u rank()