I would prefer to avoid the hassle of encoding and decoding,
你不能完全避免这种情况。分类变量所需的元数据实际上是值和索引之间的映射。不过,不需要手动或create a custom transformer。假设您有这样的数据帧:import numpy as np
import pandas as pd
df = sqlContext.createDataFrame(pd.DataFrame({
"x1": np.random.random(1000),
"x2": np.random.choice(3, 1000),
"x4": np.random.choice(5, 1000)
}))
您只需要一个汇编程序和索引器:
^{pr2}$
这个例子还显示了您提供了什么类型的信息来将向量的给定元素标记为类别变量{
'idx': 2, # Index (position in vector)
'name': 'x4', # name
'ord': False, # is ordinal?
# Mapping between value and label
'vals': ['0.0', '1.0', '2.0', '3.0', '4.0']
}
所以,如果你想从头开始构建这个系统,你只需做正确的模式:from pyspark.sql.types import *
from pyspark.mllib.linalg import VectorUDT
# Lets assume we have only a vector
raw = transformed.select("features_raw")
# Dictionary equivalent to transformed.schema.fields[-1].metadata shown abov
meta = ...
schema = StructType([StructField("features", VectorUDT(), metadata=meta)])
sqlContext.createDataFrame(raw.rdd, schema)
但是由于需要序列化、反序列化,所以效率很低。在
由于Spark 2.2您还可以使用元数据参数:df.withColumn("features", col("features").alias("features", metadata=meta))