Spark:包含多列的Pivot

时间:2017-03-22 16:34:45

标签: scala apache-spark dataframe apache-spark-sql pivot

我在Spark中阅读了以下json文件:

{"id" : "123", "category" : "A"}
{"id" : "456", "category" : "B"}
{"id" : "567", "category" : "C"}
{"id" : "678", "category" : "D"}
{"id" : "789", "category" : "E"}
{"id" : "123", "category" : "B"}
{"id" : "123", "category" : "C"}

我希望pivot生成mxn类别矩阵。以下是我的代码:

val df = spark.read.json("test.json")
val pivots = df.groupBy("category").pivot("category").count()
pivots.show()

这会生成以下输出:

+--------+----+----+----+----+----+
|category|   A|   B|   C|   D|   E|
+--------+----+----+----+----+----+
|       E|null|null|null|null|   1|
|       B|null|   2|null|null|null|
|       D|null|null|null|   1|null|
|       C|null|null|   2|null|null|
|       A|   1|null|null|null|null|
+--------+----+----+----+----+----+

我真正想做的是,按id进行转动并显示此矩阵中的计数。例如。 id' 123'已映射到类别ABC,因此我希望上述矩阵显示1A-A和{A-B的值{1}}(反之亦然),目前,它仅显示A-C的{​​{1}}值。

我将代码更改为1' id'但是这会在第一列产生A-A值,而我想要类别。

我有什么方法可以做到这一点(可能采用完全不同的方法)?

1 个答案:

答案 0 :(得分:3)

Fist重命名列并应用自联接:

val leftRight = df
  .withColumnRenamed("category", "left")
  .join(df.withColumnRenamed("category", "right"), Seq("id"))

获取每个id的共现。接下来应用crosstab

leftRight.stat.crosstab("left", "right")

汇总所有ID的数据。结果是:

+----------+---+---+---+---+---+
|left_right|  A|  B|  C|  D|  E|
+----------+---+---+---+---+---+
|         E|  0|  0|  0|  0|  1|
|         A|  1|  1|  1|  0|  0|
|         B|  1|  2|  1|  0|  0|
|         C|  1|  1|  2|  0|  0|
|         D|  0|  0|  0|  1|  0|
+----------+---+---+---+---+---+