当前位置: 首页 > 知识库问答 >
问题:

火花-从嵌套数组中的结构中选择列时出错

尉迟正奇
2023-03-14

============更新==========

我在我的JSON中添加了一些更多的细节(struct_c和array_d)以使它更清楚地知道我在哪里得到了异常。

===============================================

我有一个带有Struct类型嵌套数组的Spark DataFrame。我想从该结构中选择一个列,但收到错误消息:“org.apache.spark.sql.analysisexception:由于数据类型不匹配,无法解析'home.array_a.array_b['a']':参数2需要整数类型,但是'a''是字符串类型”。

下面是我的数据:

{
  "home": {
    "a_number": 5,
    "a_string": "six",
    "array_a": [
      {
        "array_b": [{"a": "1", "b": 2}],
        "struct_c": {"a": 1.1, "b": 1.3},
        "array_d": ["a", "b", "c"]
      },
      {
        "array_b": [{"a": "3", "b": 4}],
        "struct_c": {"a": 1.5, "b": 1.6},
        "array_d": ["x", "y", "z"]
      }
    ]
  }
}

下面是我的数据架构:

mydf1 = spark.read.option("multiline", "true").json("myJson.json")
mydf1.printSchema()

root
 |-- home: struct (nullable = true)
 |    |-- a_number: long (nullable = true)
 |    |-- a_string: string (nullable = true)
 |    |-- array_a: array (nullable = true)
 |    |    |-- element: struct (containsNull = true)
 |    |    |    |-- array_b: array (nullable = true)
 |    |    |    |    |-- element: struct (containsNull = true)
 |    |    |    |    |    |-- a: string (nullable = true)
 |    |    |    |    |    |-- b: long (nullable = true)
 |    |    |    |-- array_d: array (nullable = true)
 |    |    |    |    |-- element: string (containsNull = true)
 |    |    |    |-- struct_c: struct (nullable = true)
 |    |    |    |    |-- a: double (nullable = true)
 |    |    |    |    |-- b: double (nullable = true)
mydf1.select("home.array_a.array_d").show(10, False)

+----------------------+
|array_d               |
+----------------------+
|[[a, b, c], [x, y, z]]|
+----------------------+

mydf1.select(col("home.array_a.struct_c.a").alias("struct_field_inside_arrayA")).show(10, False)

+--------------------------+
|struct_field_inside_arrayA|
+--------------------------+
|[1.1, 1.5]                |
+--------------------------+

这就是它失败的地方:

mydf1.select("home.array_a.array_b.a").printSchema()
mydf1.select("home.array_a.array_b.a").show()

我所期望的是一个二维string数组([[“1”,“3”]]是我的示例JSON)

你能帮我解释一下它失败的原因吗?

共有1个答案

淳于博
2023-03-14

既然您对element_at()函数没有任何问题,我假设您使用的是spark 2.4+,那么您可以尝试spark SQL内置函数:transform[1][2]+Flatten:

>>> mydf1.selectExpr('flatten(transform(home.array_a.array_b, x -> x.a)) as array_field_inside_array').show()
+------------------------+
|array_field_inside_array|
+------------------------+
|                  [1, 3]|
+------------------------+

其中我们使用transform()函数只检索home.array_a.array_b的每个数组元素的字段a的值,并将它们转换为数组[[1],[3]]。然后将该数组扁平化为[1,3]。如果您需要结果为[[1,3]],那么只需添加数组()函数即可

array(flatten(transform(home.array_a.array_b, x -> x.a)))
 类似资料:
  • 问题内容: 我已经开始使用https://mholt.github.io/json-to-go/将API JSON转换为go结构,但我真的很喜欢它,但是我仍然坚持如何在Report Definition结构中初始化Filters数组结构如下所示。 我似乎无法引用在Filters结构甚至是Filters结构中声明的项,以创建新的Filter项目并将其附加到Filters。 是否可以使用原样编写的Re

  • 问题内容: 我创建了一个客户c#DropDownList控件,可以将其内容呈现为optgroup(不是从头开始,我编辑了一些在Internet上找到的代码,尽管我确切地了解了它的作用),并且工作正常。 但是,我现在遇到一种情况,我需要在下拉菜单中有两个缩进级别,即 但是,在上面的示例代码段中,它呈现的缩进量与相同。 有没有一种方法可以产生我想要的嵌套optgroup行为? 问题答案: 好的,如果有

  • 我正在运行以下scala代码: 我知道firstStruct是structType,StructFields的一个名称是“name”,但在尝试强制转换时似乎失败了。我被告知spark/hive结构与scala不同,但为了使用structType,我需要 所以我想他们应该是同一种类型的。 我看了看这里:https://github.com/apache/spark/blob/master/sql/c

  • 问题内容: 在SQL Server中, 您可以这样编写嵌套的SQL: 这样,我可以获得一个可以嵌套到其他查询中的临时表T。 但是我不能在oracle SQL中做同样的事情 它给我 选择*有效,但这不是我想要的。有人知道该怎么做吗? 问题答案: 无论我显式指定别名还是指定,您发布的查询都对我有效。收到异常后,您可以发布正在运行的确切查询吗? 我的猜测是您要选择不带双引号的内容。如果在Oracle中使

  • 我正在尝试使用“psycopg2”从postgres获取JSON行。记录的值类似于[[{….},{...},{...}] ]. 要获得正确的JSON结果,请执行以下操作:[{…},{...},{...}] 我得去录音。不知道为什么会这样。

  • 假设我有一张这样的桌子: 它以拼花地板的形式存储。我需要在spark中读取表,在“field1”上执行groupBy,然后我需要在ES中存储一个嵌套字段(例如,称为“agg\u字段”),其中包含一个字典列表,其中包含字段2和字段3的值,这样文档将如下所示: 我可以阅读表格并进行分组: 我可以做一些聚合并将结果发送给es: 但我不知道如何将聚合更改为嵌套的“agg\u fields”列,该列将被el