簡體   English   中英

在Spark-Scala中,如何將列表數組復制到DataFrame中?

[英]In Spark-Scala, how to copy Array of Lists into DataFrame?

我熟悉Python,並且正在學習Spark-Scala。

我想建立一個DataFrame,其結構由以下語法描述:

// Prepare training data from a list of (label, features) tuples.
val training = spark.createDataFrame(Seq(
  (1.1, Vectors.dense(1.1, 0.1)),
  (0.2, Vectors.dense(1.0, -1.0)),
  (3.0, Vectors.dense(1.3, 1.0)),
  (1.0, Vectors.dense(1.2, -0.5))
)).toDF("label", "features")

我從此URL獲得了以上語法: http : //spark.apache.org/docs/latest/ml-pipeline.html

目前,我的數據是從DF取出的數組中:

val my_a = gspc17_df.collect().map{row => Seq(row(2),Vectors.dense(row(3).asInstanceOf[Double],row(4).asInstanceOf[Double]))}

我的數組的結構與上面的DF非常相似:

my_a: Array[Seq[Any]] =
Array(
  List(-1.4830674013266898, [-0.004192832940431825,-0.003170667657263393]),
  List(-0.05876766500768526, [-0.008462913654529357,-0.006880595828929472]),
  List(1.0109273250546658, [-3.1816797620416693E-4,-0.006502619326182358]))

如何將數據從我的數組復制到具有上述結構的DataFrame中?

我嘗試了以下語法:

val my_df = spark.createDataFrame(my_a).toDF("label","features")

星巴克向我咆哮:

<console>:105: error: inferred type arguments [Seq[Any]] do not conform to method createDataFrame's type parameter bounds [A <: Product]
       val my_df = spark.createDataFrame(my_a).toDF("label","features")
                         ^
<console>:105: error: type mismatch;
 found   : scala.collection.mutable.WrappedArray[Seq[Any]]
 required: Seq[A]
       val my_df = spark.createDataFrame(my_a).toDF("label","features")
                                         ^
scala> 

這里的第一個問題是您使用List存儲行數據。 List是同構數據結構,並且由於Anyrow(2) )和DenseVector的唯一常見類型是AnyObject ),因此您最終得到Seq[Any]

下一個問題是您完全使用row(2) 由於Row實際上是Any的集合,因此此操作不會返回任何有用的類型,並且DataFrame不提供顯式的Encoder就無法將結果存儲在DataFrame

從更閃亮的角度來看,這也不是一個好方法。 collect -int僅用於轉換數據,不需要任何注釋,並且。 Rows上進行映射以僅創建Vectors也沒有太大意義。

假設沒有類型不匹配,則可以使用VectorAssembler

import org.apache.spark.ml.feature.VectorAssembler

val assembler = new VectorAssembler()
  .setInputCols(Array(df.columns(3), df.columns(4)))
  .setOutputCol("features")

assembler.transform(df).select(df.columns(2), "features")

或者,如果您真的想手動處理此問題,則使用UDF

val toVec = udf((x: Double, y: Double) => Vectors.dense(x, y))

df.select(col(df.columns(2)), toVec(col(df.columns(3)), col(df.columns(4))))

通常,強烈建議您在開始使用Spark之前先熟悉Scala。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM