如何在Spark中将STRUCT的所有元素与1000多个元素结合在一起

回归器

我有一个火花数据框,如下所示,带有一个struct字段。

val arrayStructData = Seq(
Row("James",Row("Java","XX",120)),
Row("Michael",Row("Java","",200)),
Row("Robert",Row("Java","XZ",null)),
Row("Washington",Row("","XX",120))
)

val arrayStructSchema = new StructType().add("name",StringType).add("my_struct", new StructType().add("name",StringType).add("author",StringType).add("pages",IntegerType))

val df = spark.createDataFrame(spark.sparkContext.parallelize(arrayStructData),arrayStructSchema)


df.printSchema()
root
 |-- name: string (nullable = true)
 |-- my_struct: struct (nullable = true)
 |    |-- name: string (nullable = true)
 |    |-- author: string (nullable = true)
 |    |-- pages: integer (nullable = true)

df.show(false)

+----------+---------------+
|name      |my_struct      |
+----------+---------------+
|James     |[Java, XX, 120]|
|Michael   |[Java, , 200]  |
|Robert    |[Java, XZ,]    |
|Washington|[, XX, 120]    |
+----------+---------------+

我想构造一个输出列final_list,该显示结构中是否存在元素。问题是,在此示例中,结构元素仅限于3个,但是在实际数据中,结构中有1,000个元素,每个记录可能包含也可能不包含每个元素中的值。

这是我要构造列的方式-

val cleaned_df = spark.sql(s"""select name, case when my_struct.name = "" then "" else "name" end as name_present
, case when my_struct.author = "" then "" else "author" end as author_present 
, case when my_struct.pages = "" then "" else "pages" end as pages_present 
from df""")
cleaned_df.createOrReplaceTempView("cleaned_df")
cleaned_df.show(false)
+----------+------------+--------------+-------------+
|name      |name_present|author_present|pages_present|
+----------+------------+--------------+-------------+
|James     |name        |author        |pages        |
|Michael   |name        |              |pages        |
|Robert    |name        |author        |pages        |
|Washington|            |author        |pages        |
+----------+------------+--------------+-------------+

因此,我case为每个列编写了一个语句以捕获其存在或不存在。然后我像下面这样进行concat以获得最终输出-

val final_df = spark.sql(s"""
select name, concat_ws("," , name_present, author_present, pages_present) as final_list
from cleaned_df
""")
final_df.show(false)
+----------+-----------------+
|name      |final_list       |
+----------+-----------------+
|James     |name,author,pages|
|Michael   |name,,pages      |
|Robert    |name,author,pages|
|Washington|,author,pages    |
+----------+-----------------+

我不能写一个巨大的case语句来捕获1000个元素的结构。有更聪明的方法吗?也许是UDF?

我正在使用Spark 2.4.3。我不知道是否有任何支持此功能的高阶函数。但是我的真实数据框的架构如下所示-

 |-- name: string (nullable = true)
 |-- my_struct: struct (nullable = true)
 |    |-- name: string (nullable = true)
 |    |-- author: string (nullable = true)
 |    |-- element3: integer (nullable = true)
 |    |-- element4: string (nullable = true)
 |    |-- element5: double (nullable = true)
 .....
 .....
 |    |-- element1000: string (nullable = true)
维纳

您已经提到过UDF。使用UDF,您可以遍历my_struct的所有字段并收集标志:

def availableFields = (in:Row) => {
  val ret = scala.collection.mutable.ListBuffer.empty[String]
  for( i <- Range(0, in.size)) {
    if( !in.isNullAt(i) && in.get(i) != "") {
      ret += in.schema.fields(i).name
    }
  }
  ret.mkString(",")
}
val availableFieldsUdf = udf(availableFields)

df.withColumn("final_list", availableFieldsUdf(col("my_struct")) ).show(false)

版画

+----------+---------------+-----------------+
|name      |my_struct      |final_list       |
+----------+---------------+-----------------+
|James     |[Java, XX, 120]|name,author,pages|
|Michael   |[Java, , 200]  |name,pages       |
|Robert    |[Java, XZ,]    |name,author      |
|Washington|[, XX, 120]    |author,pages     |
+----------+---------------+-----------------+

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在MongoDB中将所有文档的数组字段组合在一起?

如何在SQL中将另一个条件与多个内部联接结合在一起?

如何在Kotlin中将多个Upper Bounds语法与委托语法结合在一起

如何在同一阵列中两个元素结合在一起?

如何在Kusto中将控制命令与参数化查询结合在一起?

如何在disp方法中将变量与字符串结合在一起?

如何在jq中将更新与函数结果结合在一起?

如何在熊猫中将布尔索引器与多索引结合在一起?

如何在Java android中将两个函数结合在一起

我如何在Python中将综合与ordereddict结合在一起?

如何在Django中将2个模型字段结合在一起?

如何在带有R的for循环中将“ paste”命令与“ ifelse”命令结合在一起?

如何在TypeScript中将有区别的联合与函数重载结合在一起

如何在一个大文件系统中将多个(1000)png文件组合在一起,如果需要,我们可以迭代并获取所有文件

如何在 BigQuery 中将多个表粘合在一起?

在PostgreSQL中将CTE与IN结合在一起

在Python中将两个时间序列与datetime索引的不同元素结合在一起

在Hibernate中将多个结果结合在一起

将一个元素与不同列的所有其他元素组合在一起 / R

将具有共同元素的两个列表结合在一起-Scala

如何在Hibernate Search中将范围查询与关键字查询结合在一起?

将数组元素组合在一起

如何在Python中将两个具有相同索引的Series组合在一起?

如何在没有任何包的情况下将列表中的“x”个元素组合在一起

如何在 Hive SQL 中将与时间相关的事件组合在一起

如何在SAS中将组合在一起的观察分组

如何在Python中将3个元组组合在一起

如何将Scala中的每个n元素组合在一起?

如何将 2 个选择元素组合在一起 html