在Spark Scala中,如何将列表数组复制到数据帧中?
我熟悉Python,正在学习Spark Scala 我想构建一个数据帧,其结构由以下语法描述:在Spark Scala中,如何将列表数组复制到数据帧中?,scala,apache-spark,Scala,Apache Spark,我熟悉Python,正在学习Spark Scala 我想构建一个数据帧,其结构由以下语法描述: // 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
// 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")
val my_df = spark.createDataFrame(my_a).toDF("label","features")
我从这个URL获得了上述语法:
目前,我的数据位于我从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]))
如何将数据从阵列复制到具有上述结构的数据帧中
我尝试了以下语法:
// 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")
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>
:105:错误:推断的类型参数[Seq[Any]]不符合方法createDataFrame的类型参数界限[A]
这里的第一个问题是使用列表来存储行数据。列表是一种同构的数据结构,因为任何(行(2)
)和DenseVector
的唯一常见类型是任何(对象),所以最终得到的是Seq[Any]
下一个问题是使用行(2)
。由于行
实际上是任何
的集合,因此此操作不会返回任何有用的类型,并且如果不提供明确的编码器
,结果无法存储在数据帧中
从更浅显的角度来看,这也不是一个好方法。collect
-int仅用于转换数据不需要任何注释和注释。映射行
仅用于创建向量
也没有多大意义
假设没有类型不匹配,您可以使用矢量汇编程序:
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。这里的第一个问题是使用List
来存储行数据。List是一种同质的数据结构,因为Any
(row(2)
)和DenseVector
是Any
(对象
)您将得到一个Seq[Any]
下一个问题是使用行(2)
。由于行
实际上是任何
的集合,因此此操作不会返回任何有用的类型,并且如果不提供明确的编码器
,结果无法存储在数据帧中
从更浅显的角度来看,这也不是一个好方法。collect
-int仅用于转换数据不需要任何注释和注释。映射行
仅用于创建向量
也没有多大意义
假设没有类型不匹配,您可以使用矢量汇编程序:
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