0

我正面临着SparkML的OneHotEncoder问题,因为它读取数据帧元数据以确定它应该为其创建的稀疏矢量对象分配的值范围。如何更新Spark 2.1上的pyspark数据框元数据?

更具体而言,我使用含0 23之间和

所有单独的值现在我得分用“改造”方法OD单行数据帧的训练组编码的“小时”字段管道。

不幸的是,这导致了OneHotEncoder

一个不同编码稀疏矢量对象(24,[5],[1.0])与(11,[10],[1.0])

我已记录这here,但这被确定为重复。因此,在这个thread有发布到更新dataframes的元数据,以反映“小时”现场的实际范围的解决方案:

from pyspark.sql.functions import col 

meta = {"ml_attr": { 
    "vals": [str(x) for x in range(6)], # Provide a set of levels 
    "type": "nominal", 
    "name": "class"}} 

loaded.transform(
    df.withColumn("class", col("class").alias("class", metadata=meta))) 

Unfortunalely我得到这个错误:

TypeError: alias() got an unexpected keyword argument 'metadata'

+0

您指向的指向是指Scala API;在pyspark 2.1中,'alias'方法没有'metadata'参数http://spark.apache.org/docs/2.1.0/api/python/pyspark.sql.html#pyspark.sql.Column.alias - this线程可能会更有用:https://stackoverflow.com/questions/44273080/how-to-change-column-metadata-in-pyspark – desertnaut

+1

帮助,非常感谢。请作为回答发布,以便我可以upvote并接受 –

+0

你是非常欢迎的 - 答复贴,信用归因 – desertnaut

回答

2

在PySpark 2.1,alias方法没有参数metadatadocs) - 这个在Spark 2.2中的became available;尽管如此,它仍然是可以修改列元在PySpark < 2.2,多亏了令人难以置信的Spark Gotchas,通过@eliasah@zero323维护:

import json 

from pyspark import SparkContext 
from pyspark.sql import Column 
from pyspark.sql.functions import col 

spark.version 
# u'2.1.1' 

df = sc.parallelize((
     (0, "x", 2.0), 
     (1, "y", 3.0), 
     (2, "x", -1.0) 
     )).toDF(["label", "x1", "x2"]) 

df.show() 
# +-----+---+----+ 
# |label| x1| x2| 
# +-----+---+----+ 
# | 0| x| 2.0| 
# | 1| y| 3.0| 
# | 2| x|-1.0| 
# +-----+---+----+ 

假设我们要执行我们label数据的可能性是0和5之间,尽管我们的数据帧是0和2之间,这里是我们应该如何修改列的元数据:

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)))) 

Column.withMeta = withMeta 

# new metadata: 
meta = {"ml_attr": {"name": "label_with_meta", 
        "type": "nominal", 
        "vals": [str(x) for x in range(6)]}} 

df_with_meta = df.withColumn("label_with_meta", col("label").withMeta("", meta)) 

荣誉也this answer通过zero323!