我有一个如下结构的超大表格:
user, product, actionuser1, productA, actionAuser1, productA, actionBuser1, productA, actionBuser2, productF, actionAuser3, productZ, actionC
我想将其转换为以下形式:
阶段1:检索特定产品的特定行为
user, productA_actionA, productB_actionA, …, productA_actionB, productB_actionB…user1, 1, 0, ..., 0,0, ...user1, 0, 0, ..., 1,0, ...user1, 0, 0, ..., 1,0, ...user2, 0, 0, ..., 0,0, ...
我有一个包含特定组合的数组:
[(productA,actionA) ,(productB,actionA) ,… ,(productA,actionB) ,(productB,actionB) …]
阶段2:按用户分组,并对其产品和行为进行求和
user, productA_actionA, productB_actionA, …, productA_actionB, productB_actionB…user1, 1, 0, ..., **2**,0, ...user2, 0, 0, ..., 0,0, ...
我尝试对每个特征使用withColumn
function
,但这花费了很长时间:
for ( (productID,productAction) <- productsCombination ) { newTable = newTable.withColumn("Product_"+productID+"_"+productAction, when(col("product_action_id") === productAction and col("product_id") === productID, $"product_count").otherwise(0))
这里有一个示例展示我想做的事情:
有什么建议吗?
回答:
我没有完全理解这个问题,但根据你的截图进行了考虑。就像T. Gawęda所说,你应该使用Pivot。请注意,pivot
仅在Spark 1.6+版本可用。
假设这是你的源DataFrame
scala> df.show()+-----+-------+---------------+| User|Product| Action|+-----+-------+---------------+|user1| A| Viewed||user1| A| Viewed||user1| A| Viewed||user1| C| AddToCart||user1| A|RemovedFromCart||user2| B| Viewed||user2| B| Viewed||user3| A| Viewed||user3| A| AddToCart||user4| B| AddToCart||user5| A| Viewed|+-----+-------+---------------+
现在,由于你需要对两列进行Pivot,你可以使用Apache Spark提供的concat_ws
函数将它们连接成一列,然后对连接后的列进行Pivot,按Users
进行groupBy
,并使用count
作为Products
的聚合函数。
df.withColumn("combined", concat_ws("_", $"Product", $"Action")) .groupBy("User") .pivot("combined") .agg(count($"Product")).show()+-----+-----------+-----------------+--------+-----------+--------+-----------+| User|A_AddToCart|A_RemovedFromCart|A_Viewed|B_AddToCart|B_Viewed|C_AddToCart|+-----+-----------+-----------------+--------+-----------+--------+-----------+|user1| 0| 1| 3| 0| 0| 1||user2| 0| 0| 0| 0| 2| 0||user3| 1| 0| 1| 0| 0| 0||user4| 0| 0| 0| 1| 0| 0||user5| 0| 0| 1| 0| 0| 0|+-----+-----------+-----------------+--------+-----------+--------+-----------+