0

I have a dataframe with single array struct column where I want to split the nested values and added as a comma separated string new column(s) Example dataframe: tests

{id:1,name:foo},{id:2,name:bar}

Expected result dataframe

tests                            tests_id  tests_name
[id:1,name:foo],[id:2,name:bar]  1, 2     foo, bar

I tried the below code but got an error

df.withColumn("tests_name", concat_ws(",", explode(col("tests.name"))))

Error:

org.apache.spark.sql.AnalysisException: Generators are not supported when it's nested in expressions, but got: concat_ws(,, explode(tests.name AS `name`));
1
  • can you share the schema of dataframe, what version of spark are you using? Commented Jun 22, 2020 at 14:54

1 Answer 1

2

Depends on the Spark version you are using. Assuming the dataframe scheme as below

root
 |-- test: array (nullable = true)
 |    |-- element: struct (containsNull = true)
 |    |    |-- id: long (nullable = true)
 |    |    |-- name: string (nullable = true) 

Spark 3.0.0

df.withColumn("id", concat_ws(",", transform($"test", x => x.getField("id"))))
  .withColumn("name", concat_ws(",", transform($"test", x => x.getField("name"))))
.show(false)

Spark 2.4.0+

df.withColumn("id", concat_ws(",", expr("transform(test, x -> x.id)")))
.withColumn("name", concat_ws(",", expr("transform(test, x -> x.name)")))
.show(false)

Spark < 2.4

val extract_id = udf((test: Seq[Row]) => test.map(_.getAs[Long]("id")))
val extract_name = udf((test: Seq[Row]) => test.map(_.getAs[String]("name")))

df.withColumn("id", concat_ws(",", extract_id($"test")))
  .withColumn("name", concat_ws(",", extract_name($"test")))
  .show(false)

Output:

+--------------------+---+-------+
|test                |id |name   |
+--------------------+---+-------+
|[[1, foo], [2, bar]]|1,2|foo,bar|
|[[3, foo], [4, bar]]|3,4|foo,bar|
+--------------------+---+-------+
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.