2015-07-13 25 views
4

我試圖運行Spark(1.3.1)Mllib k-means聚類浮點數的數據幀。 我以下通過火花Spark Mllib kmeans示例,用數據幀代替textFile

https://spark.apache.org/docs/1.3.1/mllib-clustering.html

然而提供的聚類例如,代替一個文本文件,我使用的是雙打的一列(爲簡單起見)構成的數據幀。我需要根據Mllib文檔將其轉換爲Kmeans函數的向量。到目前爲止,我有這個

import org.apache.spark.mllib.linalg.Vectors 
    val parsedData = data.map(s => Vectors.dense(s(0))).cache() 

,我收到錯誤

error: overloaded method value dense with alternatives: 
(values: Array[Double])org.apache.spark.mllib.linalg.Vector and 
(firstValue: Double,otherValues: Double*)org.apache.spark.mllib.linalg.Vector 
cannot be applied to (Any) 
val parsedData = sample2.map(s => Vectors.dense(s(1))).cache() 
             ^

是否有這樣做的更好的辦法?

我已閱讀本類似的帖子,但我沒有找到它足夠類似: How to turn a known structured RDD to Vector 這一個How to convert org.apache.spark.rdd.RDD[Array[Double]] to Array[Double] which is required by Spark MLlib 與文本數據涉及

+0

所以這個問題存在於Hadoop集羣,其中一個表是使用蜂巢查詢上運行星火的情況下。因此數據幀。隨着越來越多的組織轉向Hadoop,我懷疑這將成爲越來越普遍的情況。 –

回答

1

什麼。 如果你在你的數據幀更多的列則只需添加更多的獲得,如:

val parsedData = data.rdd.map(s => Vectors.dense(s.getDouble(0),s.getDouble(1))).cache() 
+0

謝謝醫生,那正是我想要做的。 –

1

由於import org.apache.spark.sql.Row可以存儲任何類型的apply方法的值一個以下特徵:

def apply(i: Int): Any 

Vectors.dense預計Double作爲參數。有幾種方法可以解決這個問題。假設您想要從列x中提取值。首先,你可以在一個行構造模式匹配:

data.select($"x").map { 
    case Row(x: Double) => Vectors.dense(x) 
} 

如果你喜歡位置的方法使用模式在從返回的值相匹配應用:

data.select($"x").map(row => row(0) match { 
    case x: Double => Vectors.dense(x) 
}) 

最後,你可以使用toDouble方法:

data.select($"x").map(r => Vectors.dense(r.getDouble(0))) 

select部分是可選的,但它更容易在一行上進行模式匹配,並保護您免受一些天真的錯誤,如p指出一個錯誤的索引get

如果想要提取更多數量的列,可以逐一進行,這可能會很麻煩。如果數據是雙打這應該工作的一列的數據幀

val parsedData = data.rdd.map(s => Vectors.dense(s.getDouble(0))).cache() 

:在這種情況下,這樣的事情可能是有用的:

data.select($"x", $"y", $"z").map(r => Vectors.dense(
    r.toSeq.map({ case col: Double => col }).toArray) 
) 
+0

在第一種情況下,你會不會寫:_parsedData = data.map {case Row(x:Double,_)=> Vectors.dense(x)} _?否則我會得到一個「類型不匹配」錯誤。 –

+0

你確定它不是'scala.MatchError'嗎?如果是的話,我已經更新了一個答案,以避免匹配整行的問題。 – zero323