从Spark Dataframe& amp;创建labledpoints如何将名称列表传递给VectorAssembler

时间:2016-06-01 17:05:44

标签: python apache-spark apache-spark-sql apache-spark-ml

我还有其他问题https://stackoverflow.com/a/32557330/5235052 我正在尝试从数据框架构建labledPoints,其中我有列中的功能和标签。这些功能都是布尔值1/0。

以下是数据框中的示例行:

|             0|       0|        0|            0|       0|            0|     1|        0|     0|           0|       0|       0|       0|           0|        0|         0|      0|            0|       0|           0|          0|         0|         0|              0|        0|        0|        0|         0|          0|    1|    0|    1|    0|    0|       0|           0|    0|     0|     0|     0|         0|         1|
#Using the code from above answer, 
#create a list of feature names from the column names of the dataframe
df_columns = []
for  c in df.columns:
    if c == 'is_item_return': continue
    df_columns.append(c)

#using VectorAssembler for transformation, am using only first 4 columns names
assembler = VectorAssembler()
assembler.setInputCols(df_columns[0:5])
assembler.setOutputCol('features')

transformed = assembler.transform(df)

   #mapping also from above link
   from pyspark.mllib.regression import LabeledPoint
   from pyspark.sql.functions import col

new_df = transformed.select(col('is_item_return'), col("features")).map(lambda row: LabeledPoint(row.is_item_return, row.features))

当我检查RDD的内容时,我得到了正确的标签,但是特征向量是错误的。

(0.0,(5,[],[]))

有人可以帮我理解,如何将现有数据框的列名作为要素名称传递给VectorAssembler?

1 个答案:

答案 0 :(得分:3)

这里没有错。你得到的是SparseVector的字符串表示,它完全反映了你的输入:

  • 您前五列(assembler.setInputCols(df_columns[0:5])),输出向量长度为​​5
  • 由于示例输入的第一列不包含非零条目indicesvalues数组为空

为了说明这一点,我们可以使用提供有用的toSparse / toDense方法的Scala:

import org.apache.spark.mllib.linalg.Vectors

val v = Vectors.dense(Array(0.0, 0.0, 0.0, 0.0, 0.0))
v.toSparse.toString
// String = (5,[],[])

v.toSparse.toDense.toString
// String = [0.0,0.0,0.0,0.0,0.0]

使用PySpark:

from pyspark.ml.feature import VectorAssembler

df = sc.parallelize([
    tuple([0.0] * 5),
    tuple([1.0] * 5), 
    (1.0, 0.0, 1.0, 0.0, 1.0),
    (0.0, 1.0, 0.0, 1.0, 0.0)
]).toDF()

features = (VectorAssembler(inputCols=df.columns, outputCol="features")
    .transform(df)
    .select("features"))

features.show(4, False)

## +---------------------+
## |features             |
## +---------------------+
## |(5,[],[])            |
## |[1.0,1.0,1.0,1.0,1.0]|
## |[1.0,0.0,1.0,0.0,1.0]|
## |(5,[1,3],[1.0,1.0])  |
## +---------------------+

它还表明汇编程序根据非零条目的数量选择不同的表示。

features.flatMap(lambda x: x).map(type).collect()

## [pyspark.mllib.linalg.SparseVector,
##  pyspark.mllib.linalg.DenseVector,
##  pyspark.mllib.linalg.DenseVector,
##  pyspark.mllib.linalg.SparseVector]