2017-09-05 62 views
-1

我想執行Spark的countVectorizer模型。作爲此要求的一部分,我正在讀取一個csv文件並從中創建一個Dataframe(inp_DF)。Spark - 如何創建一個Spark數據框,其中包含countVectorizer模型的其中一列的值數組

它有3列如下所示

+--------------+--------+-------+ 
|   State|Zip Code|Country| 
+--------------+--------+-------+ 
|  kentucky| 40205|  us| 
|  indiana| 47305|  us| 
|greater london| sw15|  gb| 
| california| 92707|  us| 
|  victoria| 3000|  au| 
|   paris| 75001|  fr| 
|  illinois| 60608|  us| 
|  minnesota| 55405|  us| 
| california| 92688|  us| 
+--------------+--------+-------+ 

我需要創建一個包含所有這些3列的值的陣列,例如

|  kentucky| 40205|  us| "kentucky","40205","us" 
|  indiana| 47305|  us| "indiana","47305","us" 
|greater london| sw15|  gb| "greater london","sw15","gb" 
| california| 92707|  us| "california","92707","us" 
|  victoria| 3000|  au| "victoria","3000","au" 
|   paris| 75001|  fr| "paris","75001","fr" 
|  illinois| 60608|  us| "illinois","60608","us" 
|  minnesota| 55405|  us| "minnesota","55405","us" 
| california| 92688|  us| "california","92688","us" 

同一數據幀中的第4列問題1:是否有像.concat這樣的簡單命令可以實現這一目標?

此數組是必需的,因爲countVectorizer模型的輸入應該是包含值數組的列。它不應該是在下面的錯誤消息中提到的字符串數據類型:線程「主」 java.lang.IllegalArgumentException異常

例外: 要求失敗:列國家的類型必須是相等的 之一以下類型:[ArrayType(StringType,true), ArrayType(StringType,false)]但實際上是StringType類型。在 scala.Predef $ .require(Predef.scala:224)在 org.apache.spark.ml.util.SchemaUtils $ .checkColumnTypes(SchemaUtils.scala:58) 在 org.apache.spark.ml.feature .CountVectorizerParams $ class.validateAndTransformSchema(CountVectorizer.scala:75) 在 org.apache.spark.ml.feature.CountVectorizer.validateAndTransformSchema(CountVectorizer.scala:123) 在 org.apache.spark.ml.feature.CountVectorizer .transformSchema(CountVectorizer.scala:188) 在 org.apache.spark.ml.PipelineStage.transformSchema(Pipeline.scala:74) 在 org.apache.spark.ml.feature.CountVectorizer.fit(C​​ountVectorizer.scala :155) at org.apache.spark.examples.ml.CountVectorizerExample $。主要(CountVectorizerExample.scala:54) 在 org.apache.spark.examples.ml.CountVectorizerExample.main(CountVectorizerExample.scala) 在sun.reflect.NativeMethodAccessorImpl .invoke0(本機方法)在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在java.lang.reflect.Method.invoke (Method.java:498)at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147) Java HotSpot(TM)客戶端VM警告:忽略選項MaxPermSize = 300m; 支撐在8.0

我試圖創建從輸入數據幀的那些3列,但數組元素的數組方括號[]內被封閉除去。下面

代碼段示例給出供參考

// Read Input Dataset for countVectorizer Logic 
val inp_data = spark.read.format("com.databricks.spark.csv").option("header", "True").option("inferSchema", "true") 
     .option("treatEmptyValuesAsNulls", "true").option("nullValue", "") 
     .load("Input.csv") 

// Creating a Spark Dataframe from the Input Data 
val inp_DF = inp_data.toDF() 

// Creating an array from Spark Dataframe Columns 
val inp_array = inp_DF.select("State","Zip Code","Country").collect() 
     println(inp_array.mkString(",")) 

// fit a CountVectorizerModel from the corpus 
val cvModel: CountVectorizerModel = new CountVectorizer() 
     .setInputCol("State") 
     .setOutputCol("features") 
     .setVocabSize(4) 
     .setMinDF(2) 
     .fit(inp_DF) 

問題2:如何從這些數組元素除去方括號[]和在與所述陣列的值的數據幀創建新列?

問題3:我們可以提供單列值作爲countVectorizer模型的輸入並獲取要素作爲輸出嗎?

回答

1

您可以使用array函數創建array column作爲

import org.apache.spark.sql.functions._ 
val inp_array = inp_DF.withColumn("arrayColumn", array("State", "Zip Code", "Country")) 

這應該給你輸出

+-------------+--------+-------+-------------------------+ 
|State  |Zip Code|Country|arrayColumn    | 
+-------------+--------+-------+-------------------------+ 
|kentucky  |40205 |us  |[kentucky, 40205, us] | 
|indiana  |47305 |us  |[indiana, 47305, us]  | 
|greaterlondon|sw15 |gb  |[greaterlondon, sw15, gb]| 
|california |92707 |us  |[california, 92707, us] | 
|victoria  |3000 |au  |[victoria, 3000, au]  | 
|paris  |75001 |fr  |[paris, 75001, fr]  | 
|illinois  |60608 |us  |[illinois, 60608, us] | 
|minnesota |55405 |us  |[minnesota, 55405, us] | 
|california |92688 |us  |[california, 92688, us] | 
+-------------+--------+-------+-------------------------+ 

,你可以使用這個dataframeCountVectorizerModel作爲

val cvModel: CountVectorizerModel = new CountVectorizer() 
    .setInputCol("arrayColumn") 
    .setOutputCol("features") 
    .setVocabSize(4) 
    .setMinDF(2) 
    .fit(inp_array) 

那回答你的前兩個問題。

現在回答你的第三個問題。 是的您只能使用CountVectorizerModel中的一列,但爲此您需要將該列轉換爲ArrayType(StringType,true),這可以通過使用上述的array函數來完成。

假設您想使用CountVectorizerModel中的State列。那麼你可以通過做

val single_arrayDF = inp_DF.withColumn("State", array("State")) 

State列的數據類型更改爲array,並用它作爲

val cvModel: CountVectorizerModel = new CountVectorizer() 
    .setInputCol("State") 
    .setOutputCol("features") 
    .setVocabSize(4) 
    .setMinDF(2) 
    .fit(single_arrayDF) 

我希望答案是有幫助的。

相關問題