我宁愿避免编码和解码的麻烦,
您无法真正完全避免这种情况。分类变量所需的元数据实际上是值和索引之间的映射。仍然不需要手动执行此 *** 作或创建自定义转换器。假设您具有如下数据框:
import numpy as npimport pandas as pddf = sqlContext.createDataframe(pd.Dataframe({ "x1": np.random.random(1000), "x2": np.random.choice(3, 1000), "x4": np.random.choice(5, 1000)}))
您只需要一个汇编器和索引器:
from pyspark.ml.feature import VectorAssembler, VectorIndexerfrom pyspark.ml import Pipelinepipeline = Pipeline(stages=[ VectorAssembler(inputCols=df.columns, outputCol="features_raw"), VectorIndexer( inputCol="features_raw", outputCol="features", maxCategories=10)])transformed = pipeline.fit(df).transform(df)transformed.schema.fields[-1].metadata## {'ml_attr': {'attrs': {'nominal': [{'idx': 1,## 'name': 'x2',## 'ord': False,## 'vals': ['0.0', '1.0', '2.0']},## {'idx': 2,## 'name': 'x4',## 'ord': False,## 'vals': ['0.0', '1.0', '2.0', '3.0', '4.0']}],## 'numeric': [{'idx': 0, 'name': 'x1'}]},## 'num_attrs': 3}}
此示例还显示了您提供的类型信息,以将向量的给定元素标记为分类变量
{ '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 vectorraw = transformed.select("features_raw")# Dictionary equivalent to transformed.schema.fields[-1].metadata shown abovmeta = ... schema = StructType([StructField("features", VectorUDT(), metadata=meta)])sqlContext.createDataframe(raw.rdd, schema)
但是由于需要序列化,反序列化,因此效率很低。
从 Spark 2.2开始, 您还可以使用元数据参数:
df.withColumn("features", col("features").alias("features", metadata=meta))
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)