2016-11-13 60 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