gpt4 book ai didi

apache-spark - 为Spark数据框中的每个组创建索引

转载 作者:行者123 更新时间:2023-12-04 04:48:53 26 4
gpt4 key购买 nike

我在Spark中有一个数据帧,有2列group_idvalue,其中value是 double 型。我想根据group_id对数据进行分组,按value对每个组进行排序,然后添加第三列index,该列代表value在该组值的位置中的位置。

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

+--------+-----+
|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开始并且排序是升序还是降序,这都不重要。

作为后续措施,请考虑以下情况:原始数据中的第三列 extra对于某些 (group_id, 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 |
+--------+-----+-----+

有没有一种方法可以添加 index列,以便不考虑 extra列,但仍将其保留?在这种情况下的输出将是
+--------+-----+-----+-----+
|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列来做到这一点
  • 复制数据
  • 删除extra
  • 执行distinct操作,这将导致原始示例
  • 中的数据
  • 使用原始解决方案
  • 计算 index
  • 将结果与第二个示例
  • 中的数据结合起来

    但是,这将涉及很多额外的计算和开销。

    最佳答案

    您可以使用Window函数基于value创建一个等级列,并按group_id进行分区:

    from pyspark.sql.window import Window
    from pyspark.sql.functions import rank, dense_rank
    # Define window
    window = Window.partitionBy(df['group_id']).orderBy(df['value'])
    # Create column
    df.select('*', rank().over(window).alias('index')).show()
    +--------+-----+-----+
    |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|
    +--------+-----+-----+

    因为,首先选择 '*',所以还要使用上述代码保留所有其他变量。但是,您的第二个示例显示您正在寻找函数 dense_rank(),该函数以无间隔的等级列形式提供:

    df.select('*', dense_rank().over(window).alias('index'))

    关于apache-spark - 为Spark数据框中的每个组创建索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42588077/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com