如何访问数组类型值并在两个不同的列中设置?

i7uaboj4  于 2021-05-27  发布在  Spark
关注(0)|答案(2)|浏览(320)

我正在学习spark,我有下面的xml,我想从中读取2个值并创建两个不同的列

<appRoot>
    <applist>
      <app type="test">
        <code>8.52544</code>
      </app>
      <app type="dev">
        <code>8.52537</code>
      </app>
    </applist>
</appRoot>

我想要
如果type=“test”,则应在新列“app\u test”中设置值(即8.52544),并
如果type=“dev”,则应在新列“app\u dev”中设置值(即8.52537)
我在下面试过了

df.select(
functions.when($"applist.app._type" === "test", $"applist.app.code").as("app_test"),
functions.when($"applist.app._type" === "dev", $"applist.app.code").as("app_dev"))

但它又回来了

app_test with value [8.52544, 8.52537]
app_dev with value [8.52544, 8.52537]

设置列的值时如何区分?
更新:

val df = spark.read
      .format("com.databricks.spark.xml")
      .option("rootTag", "appRoot")
      .option("rowTag", "applist")
      .load("test.xml")

    df.printSchema()

root
 |-- app: array (nullable = true)
 |    |-- element: struct (containsNull = true)
 |    |    |-- _type: string (nullable = true)
 |    |    |-- code: double (nullable = true)
kgqe7b3p

kgqe7b3p1#

使用map\从\项将数组转换为map _type 作为钥匙和 code 作为价值观。然后可以使用Map创建两个新列。

val df = spark.read.format("com.databricks.spark.xml")
   .option("rootTag", "appRoot").option("rowTag","applist")
   .load(...)

df.withColumn("map", map_from_entries('app))
   .withColumn("app_test", 'map("test"))
   .withColumn("app_dev", 'map("dev"))
   .drop('map)
   .show(false)

打印(带有一些附加测试数据)

+--------------------------------------------+--------+-------+
|app                                         |app_test|app_dev|
+--------------------------------------------+--------+-------+
|[[test, 8.52544], [dev, 8.52537], [x, 1.23]]|8.52544 |8.52537|
|[[test, 1.2], [dev, 3.4], [X, 9.9]]         |1.2     |3.4    |
|[[dev, -5.6], [Z, -12.9]]                   |null    |-5.6   |
+--------------------------------------------+--------+-------+
owfi6suc

owfi6suc2#

您可以通过以下方式实现:
将数据读入Dataframe。

val df = spark.read.format("com.databricks.spark.xml").option("rootTag", "appRoot").option("rowTag","applist").load("/home/shrey/Downloads/mydoc.xml")
df.printSchema()
df.show()


最后,您可以在when条件下通过分解数组来选择适当的列:

df.select(explode($"app").as("app")).select(functions.when($"app._type" === "test", $"app.code").as("app_test"),functions.when($"app._type" === "dev", $"app.code").as("app_dev")).show(false)


如果您希望输出在一行中,可以使用max()函数进行聚合。

df.select(explode($"app").as("app")).select(functions.when($"app._type" === "test", $"app.code").as("app_test"),functions.when($"app._type" === "dev", $"app.code").as("app_dev")).agg(max($"app_test").as("app_test"),max($"app_dev").as("app_dev")).show(false)

相关问题