简短版本:如何将嵌套数组中的每个条目转换为其他内容(例如struct)?
如何转换:
+---------+
|column_a |
+---------+
|[A, B, C]|
|[D, E] |
|[F] |
|[] |
+---------+
对此:
+---------+---------------------------+
|column_a |column_b |
+---------+---------------------------+
|[A, B, C]|[[A, aa], [B, bb], [C, cc]]|
|[D, E] |[[D, dd], [E, ee]] |
|[F] |[[F, ff]] |
|[] |[] |
+---------+---------------------------+
长版:
假设存在一个DataFrame,其中的column_A
包含字符串数组:
val schema = Seq(
StructField("column_a", ArrayType(StringType), true)
)
val data = Seq(
Row(Array("A", "B", "C")),
Row(Array("D", "E")),
Row(Array("F")),
Row(Array())
)
val df = spark.createDataFrame(
spark.sparkContext.parallelize(data),
StructType(schema)
)
df.show(false)
+---------+
|column_a |
+---------+
|[A, B, C]|
|[D, E] |
|[F] |
|[] |
+---------+
我想以以下DataFrame结尾:
val schema2 = List(
StructField("column_a", ArrayType(StringType)),
StructField("column_b", ArrayType(StructType(
Array(StructField("colA", StringType), StructField("colB", StringType))
)))
)
val data2 = Seq(
Row(Array("A", "B", "C"),
Array(Row("A", "aa"), Row("B", "bb"), Row("C", "cc"))),
Row(Array("D", "E"),
Array(Row("D", "dd"), Row("E", "ee"))),
Row(Array("F"),
Array(Row("F", "ff"))),
Row(Array(), Array())
)
val df2 = spark.createDataFrame(
spark.sparkContext.parallelize(data2),
StructType(schema2)
)
df2.show(false)
+---------+---------------------------+
|column_a |column_b |
+---------+---------------------------+
|[A, B, C]|[[A, aa], [B, bb], [C, cc]]|
|[D, E] |[[D, dd], [E, ee]] |
|[F] |[[F, ff]] |
|[] |[] |
+---------+---------------------------+
column_b
中的值应使用column_A
条目生成。对于column_A
中的每个条目,column_B
中都有一个新结构。
Spark 2.3.1中实现此目的的有效方法是什么?
(我希望使用DSL,尽管可以接受SQL。)
答案 0 :(得分:2)
您可以使用Localtime= time.asctime(time.localtime(time.time()))
Print(localtime)
来实现:
UDF
这将给出:
val transform = udf((arr: Seq[String]) => {
arr.map(v => (v, v.toLowerCase()*2))
})
df.withColumn("column_b", transform($"column_a")).show(false)
答案 1 :(得分:0)
Python版本
from pyspark.sql.functions import udf
from pyspark.sql.types import ArrayType, StringType
def my_func(arr):
return list(map(lambda s: s.lower()*2, arr))
transform = udf(my_func, ArrayType(StringType()))
df.withColumn("column_b", transform("column_a"))