如何将具有3列的关系数据集转换为2d稀疏矩阵?

时间:2016-08-17 12:10:51

标签: scala apache-spark

我正在使用带有scala 2.11的spark 2.0.0。

我有一个包含3列的数据框:

object_id  category_id   count
1          653           5
1          78            1
1          28            6
2          63            2
3          59            7

如何将其转换为此格式?

1 653:5 78:1 28:6
2 63:2
3 59:7

干杯

3 个答案:

答案 0 :(得分:1)

使用RDD&#39>

yourDS.rdd
  .map(row => (row.getInt(0), row.getInt(1), row.getInt(2)))
  .grou‌​pBy({ (oid, cid, c) => iod })
  .map({ 
    (oid, iter) => (oid, iter.foldLeft("")((a‌​cc, tup) => acc + " " + tup._2 + ":" + tup._3))
  })
  .toDF("id", "hash")

由于必须组合列,因此保持DataSet世界会有点困难。

答案 1 :(得分:1)

我的方法使用DataFrame代替RDD s,所以它与其他答案不同。

import org.apache.spark.sql.functions._
import org.apache.spark.sql.types.StringType
import scala.collection.mutable.WrappedArray


val a = sc.parallelize(Array(
  (1, 653, 5),
  (1, 78, 1),
  (1, 28, 6),
  (2, 63, 2),
  (3, 59, 7)
)).toDF("object_id", "category_id", "count")

val x = a.select(col("object_id"), concat(col("category_id"), lit(":") , col("count")).as("res"))

def concat_things(a: WrappedArray[String]) = a.reduce(_ + " " + _)

val conUDF = udf(concat_things _, StringType)

x.groupBy("object_id").agg(collect_list(col("res")).as("res")).select(col("object_id"), conUDF(col("res"))).show()

//+---------+---------------+
//|object_id|       UDF(res)|
//+---------+---------------+
//|        1|653:5 78:1 28:6|
//|        3|           59:7|
//|        2|           63:2|
//+---------+---------------+

您可以在published notebook

上查看此答案

答案 2 :(得分:0)

不想让这个家伙得不到答案 - 在pivot完全符合我的要求后,groupBy函数就会结束。

dataset .groupBy("object_id") .pivot("category_id", listOfAllCategoryIds)