2014-12-06 184 views
2

我使用Spark的Sparkl(v1.1.0)和Scala的MLlib來將k-means聚類應用於帶有點(經度和緯度)的文件。 我的文件包含4個以逗號分隔的字段(最後兩個是經度和緯度)。如何在Scala中將Array [(Double,Double)]轉換爲Array [Double]?

在這裏,它是K-意味着使用星火聚類的例子: https://spark.apache.org/docs/1.1.0/mllib-clustering.html

我想要做的就是閱讀我的文件,這些文件在HDFS的特定目錄中最後兩個字段,將其轉化爲一個RDD<Vector>Ø在KMEANS類使用此方法: train(RDD<Vector> data, int k, int maxIterations)

這是我的代碼:

val data = sc.textFile("/user/test/location/*") val parsedData = data.map(s => Vectors.dense(s.split(',').map(fields => (fields(2).toDouble,fields(3).toDouble))))

但是,當我在火花shell中運行它,我得到以下錯誤:

error: overloaded method value dense with alternatives: (values: Array[Double])org.apache.spark.mllib.linalg.Vector (firstValue: Double,otherValues: Double*)org.apache.spark.mllib.linalg.Vector cannot be applied to (Array[(Double, Double)])

所以,我不知道如何我的數組[(雙人間,雙人間)]轉化爲數組[雙]。也許有另一種方式來閱讀這兩個領域,並將其轉換爲RDD<Vector>,任何建議?

回答

1

使用flatMap的先前建議基於假設您想要映射由.split(「,」)給出的數組元素,並且通過使用Array而不是Tuple2來滿足類型。

.map/.flatMap函數收到的參數是原始集合的一個元素,因此爲了清晰起見應該命名爲'field'(單數)。調用字段(2)選擇拆分的每個元素的第三個字符 - 因此是混淆的根源。

如果你是後是.split(「」)陣列的第三和第四元素,轉化爲雙:

s.split(",").drop(2).take(2).map(_.toDouble) 

,或者如果你想所有,但第一個字段轉換成雙(如果可能超過2):

s.split(",").drop(2).map(_.toDouble) 
1

有很稠密載體兩個「工廠」的方法:

def dense(values: Array[Double]): Vector 
def dense(firstValue: Double, otherValues: Double*): Vector 

儘管上述提供的類型是Array[Tuple2[Double,Double]],因此不輸入匹配:
(提取上述:)

邏輯
val parseLineToTuple: String => Array[(Double,Double)] = s => s=> s.split(',').map(fields => (fields(2).toDouble,fields(3).toDouble)) 

這裏需要的是從輸入字符串中創建一個新的數組,如下所示:(再次只關注特定的解析邏輯)

val parseLineToArray: String => Array[Double] = s=> s.split(",").flatMap(fields => Array(fields(2).toDouble,fields(3).toDouble))) 

整合,在原代碼就可以解決這個問題:

val data = sc.textFile("/user/test/location/*") 
val vectors = data.map(s => Vectors.dense(parseLineToArray(s)) 

(當然你也可以內嵌代碼,我隔在這裏把重點放在手頭的問題)

1
val parsedData = data.map(s => Vectors.dense(s.split(',').flatMap(fields => Array(fields(2).toDouble,fields(3).toDouble)))) 
+0

我已經這樣做了,但它不起作用。我的文件的 一個例子是: 點1,綠色,30.6894754264,-17.543308253 但是,當我應用上面的代碼,其結果是: 'parsedData.take(1) 數組[org.apache.spark.mllib。 linalg.Vector] = Array([108.0,97.0,108.0,97.0,46.0,54.0,55.0,46.0])' 這就像它需要我的文件的每個字段,它應用flatMap方法,它需要從位置2到字符結束,然後它將它們變成雙重。 我需要的是隻採取我的文件的最後兩個領域。 – artemisa 2014-12-07 15:07:22