I have a Spark Dataframe with the following contents:
| Name | E1 | E2 | E3 |
|---|---|---|---|
| abc | 4 | 5 | 6 |
I need the various E columns to become rows in a new column as shown below:
| Name | value | EType |
|---|---|---|
| abc | 4 | E1 |
| abc | 5 | E2 |
| abc | 6 | E3 |
This answer
gave me the idea of using explode and I now have the following code:
df.select($"Name", explode(array("E1", "E2", "E3")).as("value"))
The above code gives me the Name and value columns I need, but I still need a way to add in the EType column based on which value in the array passed to explode is being used to populate that particular row.
Output of the above code:
| Name | value |
|---|---|
| abc | 4 |
| abc | 5 |
| abc | 6 |
How can I add the Etype column?
(I am using Spark 2.2 with Scala)
Thanks!
CodePudding user response:
You need to use melt operation here.
Note: Melt functionality is not present in pyspark, you need write that util function.
You can go thought this answer on how to implement melt function How to melt Spark DataFrame?
CodePudding user response:
Instead of exploding just value, you can explode a struct that contains the name of the column and its content, as follows:
import org.apache.spark.sql.functions.{array, col, explode, lit, struct}
val result = df
.select(
col("name"),
explode(array(
df.columns.filterNot(_ == "name").map(c => struct(lit(c).as("EType"), col(c).alias("value"))): _*
))
)
.select("name", "col.*")
With your input you will get as result dataframe:
---- ----- -----
|name|EType|value|
---- ----- -----
|abc |E1 |4 |
|abc |E2 |5 |
|abc |E3 |6 |
---- ----- -----
CodePudding user response:
You can use stack function for this particular case.
df.selectExpr('Name', "stack(3, E1, 'E1', E2, 'E2', E3, 'E3')").toDF('Name', 'value', 'EType').show()
df.selectExpr('Name', "stack(3, E1, 'E1', E2, 'E2', E3, 'E3')").toDF('Name', 'value', 'EType').show()
df.selectExpr('Name', "stack(3, E1, 'E1', E2, 'E2', E3, 'E3')").toDF('Name', 'value', 'EType').show()
---- ----- -----
|Name|value|EType|
---- ----- -----
| abc| 4| E1|
| abc| 5| E2|
| abc| 6| E3|
---- ----- -----
