我从XML文件创建了一个DataFrame。创建的DataFrame具有以下方案。
val df = hiveContext.read.format("com.databricks.spark.xml").option("rowTag", row_tag_name).load(data_dir_path_xml)
df.printSchema()
root
|-- samples: struct (nullable = true)
| |-- sample: array (nullable = true)
| | |-- element: struct (containsNull = true)
| | | |-- abc: string (nullable = true)
| | | |-- def: long (nullable = true)
| | | |-- type: string (nullable = true)
|-- abc: string (nullable = true)
我想屏蔽数据帧中的abc / def。
我能够到达我想要的领域:
val abc = df.select($"samples.sample".getField("abc"))
但我想在数据帧df中屏蔽字段abc / def(用XXXX替换abc字段)。请帮帮我
答案 0 :(得分:0)
databricks xml库中似乎没有太多(如果有的话)支持来操作基于XML的数据帧的内容(能否使用XSLT会不会很酷?! )。但是你总是可以直接操纵推断的行,例如
val abc = df.map(row => {
val samples = row.getStruct(0).getSeq(0)
val maskedSamples = samples.map(sample => {
Row("xxxxx", sample.getLong(1), sample.getString(2))
}
Row(Row(maskedSamples), row.getString(1))
}
上面的代码可能与您想要的转换不完全匹配,因为它有点不清楚,但您明白了。
答案 1 :(得分:0)
我建议您将samples array
structType
拆分为columns
(StructFields
),以便您可以根据需要屏蔽/替换它们。如果您愿意,也可以稍后申请dataframe functions
下面是分成三列的代码
df.withColumn("abcd", lit($"samples.sample.abc"))
.withColumn("def", lit($"samples.sample.def"))
.withColumn("type", lit($"samples.sample.type"))
如果需要,您可以删除samples column
.drop("samples")
由于您要使用XXXX屏蔽abc
和def
,您可以
df.withColumn("abcd", lit("XXXX"))
.withColumn("def", lit("XXXX"))
.withColumn("type", lit($"samples.sample.type"))
.drop("samples")
注意:abcd column name
被使用,因为您的架构中已有另一个column
abc
编辑以满足以下@Raj评论:
如果要保留original schema
并且不需要单独columns
,那么创建case class
和udf
函数应该可以解决问题
def mask = udf((typ: mutable.WrappedArray[String]) => Raj("XXXXX", Option(0L), typ(0)))
需要Case class
Raj
case class Raj(abc : String,
dfe : Option[Long],
typ: String)
最后在udf
type
来调用withColumn
函数
df.withColumn("samples", struct(array(mask(col("samples.sample.type"))) as "sample"))
这应该可以获得工作输出