首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Spark get嵌套对象的数据类型

Spark get嵌套对象的数据类型
EN

Stack Overflow用户
提问于 2018-01-15 23:20:32
回答 2查看 2.5K关注 0票数 2

我有一些JSON数据,如下所示:

代码语言:javascript
运行
复制
{
    "key1":"value1",
    "key2":[
        1,
        2,
        3
    ],
    "key3":{
        "key31":"value31",
        "key32":"value32"
    },
    "key4":[
        {
            "key41":"value411",
            "key42":"value412",
            "key43":"value413"
        },
        {
            "key41":"value421",
            "key42":"value422",
            "key43":"value423"
        }
    ],
    "key5":{
        "key51":[
            {
                "key511":"value511",
                "key512":"value512",
                "key513":"value513"
            },
            {
                "key511":"value521",
                "key512":"value522",
                "key513":"value523"
            }
        ]
    },
    "key6":{
        "key61":{
            "key611":[
                {
                    "key_611":"value_611",
                    "key_612":"value_612",
                    "key_613":"value_613"
                },
                {
                    "key_611":"value_621",
                    "key_612":"value_622",
                    "key_613":"value_623"
                },
                {
                    "key_611":"value_621",
                    "key_612":"value_622",
                    "key_613":"value_623"
                }
            ]
        }
    }
}

它包含简单、复杂和数组类型值的混合。

如果我尝试获取key1 schema.("key1").dataType的数据类型,则会得到StringType,key2、key3和key4也是如此。

对于key5,我也得到了StructType

但是,当我尝试获取key51的数据类型时,我得到了以下错误:

代码语言:javascript
运行
复制
java.lang.IllegalArgumentException: Field "key5.key51" does not exist.
  at org.apache.spark.sql.types.StructType$$anonfun$apply$1.apply(StructType.scala:264)
  at org.apache.spark.sql.types.StructType$$anonfun$apply$1.apply(StructType.scala:264)
  at scala.collection.MapLike$class.getOrElse(MapLike.scala:128)
  at scala.collection.AbstractMap.getOrElse(Map.scala:59)
  at org.apache.spark.sql.types.StructType.apply(StructType.scala:263)
  ... 48 elided

我的主要目的是能够分解一个给定的类型,如果它的ArrayType,而不是任何其他类型的爆炸。

explode函数能够正确识别这个给定的键(key5.key51)并分解数组。但问题在于确定数据类型。

对我来说,一种可能的解决方案是选择key5.key51作为单独的列key51,然后分解该列。

但是,有没有更好、更优雅的方法来实现这一点,同时仍然能够确定给定列的数据类型呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-01-16 01:55:11

最简单的解决方案是对感兴趣的字段执行select,然后检索模式:

代码语言:javascript
运行
复制
df.select("key5.key51").schema.head.dataType

直接使用完整模式需要遍历模式,而使用嵌入式.StructTypes和复杂类型(MapsArrays)可能很难做到这一点。

票数 4
EN

Stack Overflow用户

发布于 2018-01-16 04:58:55

下面是查找所有ArrayType字段名称的一些(递归)代码:

代码语言:javascript
运行
复制
import org.apache.spark.sql.types._

def findArrayTypes(parents:Seq[String],f:StructField) : Seq[String] = {
  f.dataType match {
    case array: ArrayType => parents
    case struct: StructType => struct.fields.toSeq.map(f => findArrayTypes(parents:+f.name,f)).flatten
    case _ => Seq.empty[String]
  }
}


val arrayTypeColumns = df.schema.fields.toSeq
  .map(f => findArrayTypes(Seq(f.name),f))
  .filter(_.nonEmpty).map(_.mkString("."))

对于您的数据帧,这将提供:

代码语言:javascript
运行
复制
arrayTypeColumns.foreach(println)


key2
key4
key5.key51
key6.key61.key611

这还不适用于map或嵌套数组中的数组

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48265845

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档