spark explode函数未按预期工作

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

我正在尝试扁平化一个复杂的xml结构,下面是xml文件-

<root>
<ATS  name="exp_Change_Rec">
<EXP1>
<EXP1INT >
<ExPFLDs>
<ExPFLD  precision="10" name="COL1" output="true"/>
<ExPFLD  precision="20" name="COL2" output="true"/>
<ExPFLD  precision="30" name="COL3" output="true"/>
<ExPFLD  precision="40" name="COL4" output="true"/>
</ExPFLDs>
</EXP1INT>
</EXP1>
</ATS>

<ATS  name="exp_Change_Flag">
<EXP1>
<EXP1INT >
<ExPFLDs>
<ExPFLD precision="10" name="COL5" output="true"/>
<ExPFLD precision="20" name="COL6" output="true"/>
<ExPFLD precision="30" name="COL7" output="true"/>
</ExPFLDs>
</EXP1INT>
</EXP1>
</ATS>
</root>

我希望输出为-

Name                  Value
exp_Change_Rec        COL1
exp_Change_Rec        COL2
exp_Change_Rec        COL3
exp_Change_Rec        COL4
exp_Change_Flag       COL5
exp_Change_Flag       COL6
exp_Change_Flag       COL7

我是通过databricks spark xml执行的,但它创建了某种笛卡尔连接-

import org.apache.spark.sql.SparkSession
import com.databricks.spark.xml.
val df1 = spark.read.option("rowTag", "root").xml("file:///home/sv-infopcdq/spark/sample.xml")
val df2 = df1.withColumn("_name", explode($"ATS._name"))
df2.withColumn("COL_NAMES", explode($"ATS.EXP1.EXP1INT.ExPFLDs.ExPFLD")).show(100)

+--------------------+---------------+--------------------+
|                 ATS|          _name|           COL_NAMES|
+--------------------+---------------+--------------------+
|[[[[[[[, COL1, tr...| exp_Change_Rec|[[, COL1, true, 2...|
|[[[[[[[, COL1, tr...| exp_Change_Rec|[[, COL5, true,],...|
|[[[[[[[, COL1, tr...|exp_Change_Flag|[[, COL1, true, 2...|
|[[[[[[[, COL1, tr...|exp_Change_Flag|[[, COL5, true,],...|

在这里,我看到col1被发布了exp\u change\u rec和exp\u change\u标志。有什么建议吗。
当我尝试分解一列时,输出工作正常,但是当我尝试分解所有列时,它显示笛卡尔连接
就像我把输出当作

Name                   Value    Precision
    exp_Change_Rec        COL1      10
    exp_Change_Rec        COL2      20
    exp_Change_Rec        COL3      30
    exp_Change_Rec        COL4      40
    exp_Change_Flag       COL5      10
    exp_Change_Flag       COL6      20
    exp_Change_Flag       COL7      30

如果我想把正确的答案扩展到包含“精确性”的话,它就不起作用了-

xml_df.withColumn("_name", ($"_name"))
    .withColumn("COL_NAMES",explode($"EXP1.EXP1INT.ExPFLDs.ExPFLD._name")
.withColumn("COL_NAMES",explode($"EXP1.EXP1INT.ExPFLDs.ExPFLD._precision")).drop("EXP1")
      .select($"_name".as("Name"), $"COL_NAMES".as("Value"))

有什么办法可以在同一层上分解多个列吗?

uxhixvfz

uxhixvfz1#

分解多个列的解决方案是

df.select(explode(arrays_zip($"col1",$col2))).select( $"col.*").show(20,false)

此解决方案可从2.4版获得+

91zkwejq

91zkwejq2#

首先,你的 rootTag 以及 rowTag 您需要更正才能继续。自从你用过 rowtag 作为父/根标记,即( root )它把整个xml看作一个记录。。。这就是你得到的单块记录不是分开的记录格式。。。具体实施情况见下表。
我用过 explode 函数,我选择你想要的精确列,如下所示。。。

val xml_df = spark.read.
      format("com.databricks.spark.xml")
      .option("rootTag", "root")
      .option("rowTag", "ATS")
      .option("nullValue","")
      .load(f.getAbsolutePath)
      xml_df.show
    xml_df.printSchema()

   val test =  xml_df.withColumn("_name", ($"_name"))
    .withColumn("COL_NAMES",explode($"EXP1.EXP1INT.ExPFLDs.ExPFLD._name")).drop("EXP1")
      .select($"_name".as("Name"), $"COL_NAMES".as("Value"))
    test.printSchema()
    test.show(100,false)

您的预期产出:

+--------------------+---------------+
|                EXP1|          _name|
+--------------------+---------------+
|[[[[[, COL1, true...| exp_Change_Rec|
|[[[[[, COL5, true...|exp_Change_Flag|
+--------------------+---------------+

root
 |-- EXP1: struct (nullable = true)
 |    |-- EXP1INT: struct (nullable = true)
 |    |    |-- ExPFLDs: struct (nullable = true)
 |    |    |    |-- ExPFLD: array (nullable = true)
 |    |    |    |    |-- element: struct (containsNull = true)
 |    |    |    |    |    |-- _VALUE: string (nullable = true)
 |    |    |    |    |    |-- _name: string (nullable = true)
 |    |    |    |    |    |-- _output: boolean (nullable = true)
 |    |    |    |    |    |-- _precision: long (nullable = true)
 |-- _name: string (nullable = true)

root
 |-- Name: string (nullable = true)
 |-- Value: string (nullable = true)

+---------------+-----+
|Name           |Value|
+---------------+-----+
|exp_Change_Rec |COL1 |
|exp_Change_Rec |COL2 |
|exp_Change_Rec |COL3 |
|exp_Change_Rec |COL4 |
|exp_Change_Flag|COL5 |
|exp_Change_Flag|COL6 |
|exp_Change_Flag|COL7 |
+---------------+-----+

相关问题