Apache spark 为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
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()
。