Scala 如何在Spark数据集中创建TypedColumn并对其进行操作?
我正在尝试使用Scala 如何在Spark数据集中创建TypedColumn并对其进行操作?,scala,apache-spark,apache-spark-dataset,Scala,Apache Spark,Apache Spark Dataset,我正在尝试使用mapGroups执行聚合,该聚合返回一个SparseMatrix作为列之一,并对列求和 我为映射的行创建了一个case类schema,以便提供列名。矩阵列的类型是org.apache.spark.mllib.linalg.matrix。如果我在执行聚合之前没有运行toDF(select(sum(“mycolumn”)),我会得到一个类型不匹配错误(required:org.apache.spark.sql.TypedColumn[MySchema,?]),如果我包含toDF我会得
mapGroups
执行聚合,该聚合返回一个SparseMatrix作为列之一,并对列求和
我为映射的行创建了一个
case类
schema,以便提供列名。矩阵列的类型是org.apache.spark.mllib.linalg.matrix。如果我在执行聚合之前没有运行toDF
(select(sum(“mycolumn”)
),我会得到一个类型不匹配错误(required:org.apache.spark.sql.TypedColumn[MySchema,?]
),如果我包含toDF
我会得到另一个类型不匹配错误:无法解析“sum(mycolumn”)'由于数据类型不匹配:函数sum需要数字类型,而不是org.apache.spark.mllib.linalg.MatrixUDT
。那么正确的方法是什么?看起来您在这里至少遇到了两个不同的问题。假设您有这样的数据集
:
val ds = Seq(
("foo", Matrices.dense(3, 2, Array(1.0, 3.0, 5.0, 2.0, 4.0, 6.0))),
("foo", Matrices.dense(3, 2, Array(1.0, 3.0, 5.0, 2.0, 4.0, 6.0)))
).toDS
ds.groupByKey(_._1).mapGroups(
(key, values) => {
val matrices = values.map(_._2.toArray)
val first = matrices.next
val sum = matrices.foldLeft(first)(
(acc, m) => acc.zip(m).map { case (x, y) => x + y }
)
(key, sum)
})
选择TypedColumn
:
- 对
使用隐式转换:$
ds.select(col("_1").as[String])
- 使用
:o.a.s.sql.functions.col
ds.select(col("_1").as[String])
- MLLib
和Matrix
不实现加法。这意味着您将无法使用MatrixUDT
函数进行+
或减少求和
- 您可以使用第三方线性代数库,但Spark SQL/Spark Dataset不支持此功能
Datsets
执行此操作,可以尝试执行以下操作:
val ds = Seq(
("foo", Matrices.dense(3, 2, Array(1.0, 3.0, 5.0, 2.0, 4.0, 6.0))),
("foo", Matrices.dense(3, 2, Array(1.0, 3.0, 5.0, 2.0, 4.0, 6.0)))
).toDS
ds.groupByKey(_._1).mapGroups(
(key, values) => {
val matrices = values.map(_._2.toArray)
val first = matrices.next
val sum = matrices.foldLeft(first)(
(acc, m) => acc.zip(m).map { case (x, y) => x + y }
)
(key, sum)
})
并映射回矩阵,但就我个人而言,我会转换为RDD并使用
breeze
看起来您在这里至少遇到了两个不同的问题。假设您有数据集
,如下所示:
val ds = Seq(
("foo", Matrices.dense(3, 2, Array(1.0, 3.0, 5.0, 2.0, 4.0, 6.0))),
("foo", Matrices.dense(3, 2, Array(1.0, 3.0, 5.0, 2.0, 4.0, 6.0)))
).toDS
ds.groupByKey(_._1).mapGroups(
(key, values) => {
val matrices = values.map(_._2.toArray)
val first = matrices.next
val sum = matrices.foldLeft(first)(
(acc, m) => acc.zip(m).map { case (x, y) => x + y }
)
(key, sum)
})
选择TypedColumn
:
- 对
使用隐式转换:$
ds.select(col("_1").as[String])
- 使用
:o.a.s.sql.functions.col
ds.select(col("_1").as[String])
- MLLib
和Matrix
不实现加法。这意味着您将无法使用MatrixUDT
函数进行+
或减少求和
- 您可以使用第三方线性代数库,但Spark SQL/Spark Dataset不支持此功能
Datsets
执行此操作,可以尝试执行以下操作:
val ds = Seq(
("foo", Matrices.dense(3, 2, Array(1.0, 3.0, 5.0, 2.0, 4.0, 6.0))),
("foo", Matrices.dense(3, 2, Array(1.0, 3.0, 5.0, 2.0, 4.0, 6.0)))
).toDS
ds.groupByKey(_._1).mapGroups(
(key, values) => {
val matrices = values.map(_._2.toArray)
val first = matrices.next
val sum = matrices.foldLeft(first)(
(acc, m) => acc.zip(m).map { case (x, y) => x + y }
)
(key, sum)
})
并映射回矩阵,但就我个人而言,我会转换为RDD并使用
breeze
谢谢。你能为加法问题提出一个解决方案吗?这就是我现在遇到的问题。矩阵是密集的还是稀疏的?大小是多少?相当小且稀疏;足够小,适合一个节点。就我个人而言,我会转换为RDD和use breeze Matrix。谢谢。你能为加法问题提出一个解决方案吗?这就是我现在的问题所在。矩阵是密集的还是稀疏的?大小是多少?相当小且稀疏;足够小,可以放在一个节点上。我个人只会转换为RDD并使用breeze矩阵。