在这两种情况下,都会丢失元数据:
udf
Column
UserDefinedFunction
将数据直接分配给Python架构对象:
df2.schema.fields[1].metadata = extract(df.schema.fields[1].metadata)
的 不是一个有效的方法 强> 一点都不火花 DataFrame 是JVM对象的东西包装器。 Python包装器中的任何更改对于JVM后端都是完全不透明的,并且根本不会传播:
DataFrame
import json df = spark.createDataFrame([(1, "foo")], ("k", "v")) df.schema[-1].metadata = {"foo": "bar"} json.loads(df._jdf.schema().json()) ## {'fields': [{'metadata': {}, 'name': 'k', 'nullable': True, 'type': 'long'}, ## {'metadata': {}, 'name': 'v', 'nullable': True, 'type': 'string'}], ## 'type': 'struct'}
甚至保存在Python中:
df.select("*").schema[-1].metadata ## {}
同 的 火花< 2.2 强> 你可以使用一个小包装(取自 Spark Gotchas ,由我和。维护 @eliasah ):
def withMeta(self, alias, meta): sc = SparkContext._active_spark_context jmeta = sc._gateway.jvm.org.apache.spark.sql.types.Metadata return Column(getattr(self._jc, "as")(alias, jmeta.fromJson(json.dumps(meta)))) df.withColumn("foo", withMeta(col("foo"), "", {...}))
同 的 Spark> = 2.2 强> 您可以使用 Column.alias :
Column.alias
df.withColumn("foo", col("foo").alias("", metadata={...}))