2016-11-13 80 views
0

我有一个数据框下方,其中最后一列代表的次用户搜索的位置数给出,并保持列索引基于另一列(在这种情况下用户)

| Hanks|   Rotterdam|  airbnb7|      1| 
|Sanders|   Rotterdam|  airbnb2|      1| 
| Hanks|   Rotterdam|  airbnb2|      3| 
| Hanks|    Tokyo|  airbnb8|      2| 
| Larry|    Hanoi|    |      2| 
| Mango|    Seoul|  airbnb5|      1| 
| Larry|    Hanoi|  airbnb1|      2| 

添加到数据帧我想要变换如下

| Hanks|   Rotterdam|  airbnb7|      1| 1| 
|Sanders|   Rotterdam|  airbnb2|      1| 1| 
| Hanks|   Rotterdam|  airbnb2|      3| 2| 
| Hanks|    Tokyo|  airbnb8|      2| 3| 
| Larry|    Hanoi|    |      2| 0| 
| Mango|    Seoul|  airbnb5|      1| 1| 
| Larry|    Hanoi|  airbnb1|      2| 1| 

请注意,第5列表示用户选择的选项(位置+停留)的唯一组合的索引。 如

| Hanks|   Rotterdam|  airbnb7|      1| 1| 
| Hanks|   Rotterdam|  airbnb2|      3| 2| 
| Hanks|    Tokyo|  airbnb8|      2| 3| 

我使用GROUPBY/AGG的通过实现UDF函数作为AGG功能下面做这个尝试。

val df2 = df1.groupBy("User", "clickedDestination", "clickedAirbnb") 
         .agg(indexUserDetailsUDF(col("clickedAirbnb")) as ("clickedAirbnbIndex")) 

而且UDF如下

var cnt = 0 
val airbnbClickIndex:(String) => String = (airbnb) => { 
    if(airbnb== "") "null" //return 0 for airbnbClickIndex when airbnb is empty 
    else{cnt+=1; cnt.toString()} //otherwise return incremented value 
} 
val indexUserDetailsUDF = udf(airbnbClickIndex) 

但是,这是行不通的。任何输入都非常感谢。 谢谢。

UPDATE1:DENSE_RANK的丹尼尔的建议做以下用户

|Meera|   Amsterdam|  airbnb12|   1|  1| 
|Meera|   Amsterdam|  airbnb2|   1|  2| 
|Meera|   Amsterdam|  airbnb7|   1|  3| 
|Meera|   Amsterdam|  airbnb8|   1|  4| 
|Meera|   Bangalore|    |   1|  5| 
|Meera|   Bangalore|  airbnb11|   1|  6| 
|Meera|   Bangalore|  airbnb8|   1|  7| 
|Meera|    Hanoi|  airbnb1|   2|  8| 
|Meera|    Hanoi|  airbnb2|   1|  9| 
|Meera|    Hanoi|  airbnb7|   1| 10| 
|Meera|   Mumbai|    |   1| 11| 
|Meera|    Oslo|    |   2| 12| 
|Meera|    Oslo|  airbnb8|   1| 13| 
|Meera|    Paris|    |   1| 14| 
|Meera|    Paris|  airbnb11|   1| 15| 
|Meera|    Paris|  airbnb6|   1| 16| 
|Meera|    Paris|  airbnb7|   1| 17| 
|Meera|    Paris|  airbnb8|   2| 18| 
|Meera|   Rotterdam|  airbnb2|   1| 19| 

我认为DENSE_RANK将推动这些记录与空字段值(在这种情况下,第3空字段)到最后。它是否正确?

+0

对于第三列中具有空值的记录,您的预期结果是什么?使用我提出的解决方案,它们将被视为普通文本,因此每个(用户,clickedDestination)对的每个空字符串都将被赋予不同的索引。 –

回答

0

如果我说得对,你可能想要一个窗口级别。你可以尝试以下方法:

import org.apache.spark.sql.functions._ 
import org.apache.spark.sql.expressions.Window 

val window = Window.partitionBy("User").orderBy("User", "clickedDestination", "clickedAirbnb") 

val result = df.withColumn("clickedAirbnbIndex", dense_rank().over(window)) 

如果需要,你可以找到关于窗口函数的一些良好的阅读中的星火here

另外,functions package api documentation非常有用。

+0

谢谢。请参阅上述更新。 – user1384205

相关问题