2017-05-14 103 views
1

據我所知,MLlib只支持整數。
然後,我想將字符串轉換爲scala中的整數。 例如,我在txtfile中有很多reviewerID,productID。在Spark MLlib中,如何將字符串轉換爲spark scala中的整數?

reviewerID productID 
03905X0912 ZXASQWZXAS 
0325935ODD PDLFMBKGMS 
... 
+0

你能詳細闡述_你要什麼用整數做「據我所知,只有MLlib整數支持。」?你將使用什麼算法。爲您的**真實**問題提供解決方案會容易得多。這可能是ALS嗎?或者其他推薦算法? –

+0

我將使用ALS算法,矩陣分解。 – DaehyunPark

回答

3

StringIndexer是解決方案。它將用估計器和變壓器裝入ML管道。本質上,一旦設置了輸入列,它就會計算每個類別的頻率並將它們從0開始編號。如果需要,您可以在管道末端添加IndexToString以替換原始字符串。

有關更多詳細信息,請參閱ML文檔以瞭解「估算,轉換和選擇特徵」。

在你的情況下,它會像:

import org.apache.spark.ml.feature.StringIndexer 

val indexer = new StringIndexer().setInputCol("productID").setOutputCol("productIndex") 
val indexed = indexer.fit(df).transform(df) 
indexed.show() 
1

您可以爲每個reviewerID(productID)添加一個具有唯一ID的新行。您可以通過以下方式添加新行。

通過monotonicallyIncreasingId

import spark.implicits._ 
val data = spark.sparkContext.parallelize(Seq(
    ("123xyx", "ab"), 
    ("123xyz", "cd") 
)).toDF("reviewerID", "productID") 
data.withColumn("uniqueReviID", monotonicallyIncreasingId).show() 

通過使用zipWithUniqueId

val rows = data.rdd.zipWithUniqueId.map { 
    case (r: Row, id: Long) => Row.fromSeq(id +: r.toSeq) 
} 

val finalDf = spark.createDataFrame(rows, StructType(StructField("uniqueRevID", LongType, false) +: data.schema.fields)) 

finalDf.show() 

您還可以通過在SQL語法使用row_number()做到這一點:

import spark.implicits._ 
val data = spark.sparkContext.parallelize(Seq(
    ("123xyx", "ab"), 
    ("123xyz", "cd") 
)).toDF("reviewerID", "productID").createOrReplaceTempView("review") 
val tmpTable1 = spark.sqlContext.sql(
    "select row_number() over (order by reviewerID) as id, reviewerID, productID from review") 

希望這有助於!

+0

At通過使用zipWithUniqueId,發生錯誤。 scala> val rows = data.rdd.zipWithUniqueId.map { | case(r:Row,id:Long)=> Row.fromSeq(id +:r.toSeq) | } :29:錯誤:未找到:類型行 情況下(R:行,ID:長)=> Row.fromSeq(ID +:r.toSeq) ^ :29:錯誤:未找到:值行 case(r:Row,id:Long)=> Row.fromSeq(id +:r.toSeq) – DaehyunPark

+0

你試過我的例子嗎?如果是的話,它應該工作。 –

相關問題