下面是我的输入DataFrame
:
+------+-------+---+------+-----+-----+-----+-----+-----+-----+
|number|word |ID |Name |prd_1|prd_2|prd_3|prd_4|prd_5|prd_6|
+------+-------+---+------+-----+-----+-----+-----+-----+-----+
|1 |bat |101|Naman |2 |3 |8 |4 |5 |10 |
|2 |abc |102|Bhagat|3 |8 |7 |9 |8 |11 |
|3 |abcd |103|Anchal|1 |9 |2 |3 |6 |12 |
|4 |abcde |104|Dev |8 |6 |9 |4 |5 |13 |
|3 |abcdef |105|PArul |2 |7 |8 |7 |3 |14 |
|1 |abcdefg|106|Vipul |3 |4 |2 |8 |4 |15 |
+------+-------+---+------+-----+-----+-----+-----+-----+-----+
现在我想将prd_1
,prd_2
,prd_3
换成一个单独的列,例如col1
和prd_4
,prd_5
,{{ 1}}至prd_6
。
以下是我正在寻找的预期输出col2
:
DataFrame
这是我尝试的:
number|word |ID |Name |col1|col2|
+------+-------+---+------+----+----+
|1 |bat |101|Naman |2 |4 |
|1 |bat |101|Naman |3 |5 |
|1 |bat |101|Naman |8 |10 |
|2 |abc |102|Bhagat|3 |9 |
|2 |abc |102|Bhagat|8 |8 |
|2 |abc |102|Bhagat|7 |11 |
|3 |abcd |103|Anchal|1 |3 |
|3 |abcd |103|Anchal|9 |6 |
|3 |abcd |103|Anchal|2 |12 |
爆炸功能仅在select语句中起作用一次,并且在连续的select语句中使用它会创建很多不必要的行,我想在单个select语句中使用爆炸7-8次。另外,我要合并到单个列中的列数将始终保持不变。
答案 0 :(得分:0)
您可以简单地zip
myArray1
和myArray2
,然后使用压缩的columNames 创建structs
并将结构收集为{{ 1}}和array
数组列。最后,您可以使用explode
表示法将struct列拆分为单独的列
.*
应将您期望的输出显示为
val zippedCols = myArray1.zip(myArray2)
val testDf = df2.withColumn("newCol", explode(array(zippedCols.map(cols => struct(col(cols._1).as("col1"), col(cols._2).as("col2"))):_*)))
.select(col("number"), col("word"), col("ID"), col("Name"), col("newCol.*"))
我希望答案会有所帮助
答案 1 :(得分:0)
这是在df上使用flatMap的另一种解决方案
urls.py
答案 2 :(得分:0)
另一种实现方式
val src_df=spark.read.option("header","true").csv("src file")
val mapped_df = src_df.groupBy(col("number"),col("word"),col("ID"),col("Name")).agg(collect_list(map($"prd_1",$"prd_4")) as "map_1",collect_list(map($"prd_2",$"prd_5")) as "map_2",collect_list(map($"prd_3",$"prd_6")) as "map_3")
def mergeUdf = udf((map1: Seq[Map[String, String]], map2: Seq[Map[String, String]],map3: Seq[Map[String, String]])=> map1.toList.flatten.toMap ++ map2.toList.flatten.toMap ++ map3.toList.flatten.toMap)
val new_df= mapped_df.withColumn("merged", mergeUdf(col("map_1"), col("map_2"),col("map_3"))).drop("map_1", "map_2","map_3")
new_df.select(col("number"),col("word"),col("ID"),col("Name"),explode($"merged")).show(false)