我正在处理以下表格,我想根据其他2列的不同值来计算新列(结果)。
| id1 | id2 | outcome
| 1 | 1 | 1
| 1 | 1 | 1
| 1 | 3 | 2
| 2 | 5 | 1
| 3 | 1 | 1
| 3 | 2 | 2
| 3 | 3 | 3
基于id1
和id2
的组合值,结果应从1开始以递增顺序开始。任何提示都可以在Scala中完成。在这种情况下,row_number
似乎没有用。
这里的逻辑是,对于id1
的每个唯一值,我们将开始使用min({id2
)对结果进行编号,而对应的id1
被分配为1。
答案 0 :(得分:1)
您可以尝试density_rank()
以您的示例
val df = sqlContext
.read
.option("sep","|")
.option("header", true)
.option("inferSchema",true)
.csv("/home/cloudera/files/tests/ids.csv") // Here we read the .csv files
.cache()
df.show()
df.printSchema()
df.createOrReplaceTempView("table")
sqlContext.sql(
"""
|SELECT id1, id2, DENSE_RANK() OVER(PARTITION BY id1 ORDER BY id2) AS outcome
|FROM table
|""".stripMargin).show()
输出
+---+---+-------+
|id1|id2|outcome|
+---+---+-------+
| 2| 5| 1|
| 1| 1| 1|
| 1| 1| 1|
| 1| 3| 2|
| 3| 1| 1|
| 3| 2| 2|
| 3| 3| 3|
+---+---+-------+
答案 1 :(得分:1)
使用Window
函数将partition
合并(first id
),然后根据order
将partition
合并成second id
。
现在,您只需要在每个dense_rank
分区上分配一个等级(Window
)。
import org.apache.spark.sql.functions._
import org.apache.spark.sql.expressions.Window
df
.withColumn("outcome", dense_rank().over(Window.partitionBy("id1").orderBy("id2")))