2017-06-02 91 views
2

我有一个DataFrame,看起来像这样:拟合一个数据帧到随机森林pyspark

+--------------------+------------------+ 
|   features|   labels | 
+--------------------+------------------+ 
|[-0.38475, 0.568...]|   label1 | 
|[0.645734, 0.699...]|   label2 | 
|  .....   |   ...  | 
+--------------------+------------------+ 

两个柱子均是字符串类型的(StringType()),我想装配到火花毫升随机森林此。为此,我需要将特征列转换为包含浮点数的矢量。有没有人有任何想法如何做?

回答

5

如果您正在使用星火2.X,我相信这是你所需要的:

from pyspark.sql.functions import udf 
from pyspark.mllib.linalg import Vectors 
from pyspark.ml.linalg import VectorUDT 
from pyspark.ml.feature import StringIndexer 

df = spark.createDataFrame([("[-0.38475, 0.568]", "label1"), ("[0.645734, 0.699]", "label2")], ("features", "label")) 

def parse(s): 
    try: 
    return Vectors.parse(s).asML() 
    except: 
    return None 

parse_ = udf(parse, VectorUDT()) 

parsed = df.withColumn("features", parse_("features")) 

indexer = StringIndexer(inputCol="label", outputCol="label_indexed") 

indexer.fit(parsed).transform(parsed).show() 
## +----------------+------+-------------+ 
## |  features| label|label_indexed| 
## +----------------+------+-------------+ 
## |[-0.38475,0.568]|label1|   0.0| 
## |[0.645734,0.699]|label2|   1.0| 
## +----------------+------+-------------+ 

随着星火1.6,它是没有太大的不同:

from pyspark.sql.functions import udf 
from pyspark.ml.feature import StringIndexer 
from pyspark.mllib.linalg import Vectors, VectorUDT 

df = sqlContext.createDataFrame([("[-0.38475, 0.568]", "label1"), ("[0.645734, 0.699]", "label2")], ("features", "label")) 

parse_ = udf(Vectors.parse, VectorUDT()) 

parsed = df.withColumn("features", parse_("features")) 

indexer = StringIndexer(inputCol="label", outputCol="label_indexed") 

indexer.fit(parsed).transform(parsed).show() 
## +----------------+------+-------------+ 
## |  features| label|label_indexed| 
## +----------------+------+-------------+ 
## |[-0.38475,0.568]|label1|   0.0| 
## |[0.645734,0.699]|label2|   1.0| 
## +----------------+------+-------------+ 

Vectors有一个parse函数,可以帮助您实现您正在尝试执行的操作。

+0

由于U,但我这样做,我得到了以下错误时: AttributeError的:“功能”对象有没有属性“_get_object_id” – abdelkarim

+0

这个确切的代码? – eliasah

+0

有了这个确切的代码,我得到这个错误: TypeError:无法序列化没有类型 但似乎我们不是在使用相同版本的火花。 事实上,我代替: 从pyspark.mllib.linalg进口向量 从pyspark.ml.linalg进口VectorUDT 附: 从pyspark.mllib.linalg进口向量,VectorUDT 和 spark.createDataFrame 与 sqlContext.createDataFrame 因为它们在我的版本 – abdelkarim

0

如果我正确理解你的问题,你有两列都包含你想要转换成双打的字符串。我现在没有机会真正测试我的代码,但是,我认为你可以这样做。该解决方案使用了一个user defined function(udf)。

import org.apache.spark.sql.functions._ 

val strToDoubleVec = udf((str: String) => { 
    Vectors.toDense(str.split(",").map(_.trim.toDouble).toArray) 
}) 

val df = data.withColumn("features", vecToDouble($(features))) 
    .withColumn("label", $"labels").cast(DoubleType)) 

我认为第一列是单个字符串,在字符串列表的情况下,您可以简单地修改udf。

+0

非常感谢您的回答,但我与pyspark工作 – abdelkarim