我在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'已映射到类别A
,B
和C
,因此我希望上述矩阵显示1
,A-A
和{A-B
的值{1}}(反之亦然),目前,它仅显示A-C
的{{1}}值。
我将代码更改为1
' id'但是这会在第一列产生A-A
值,而我想要类别。
我有什么方法可以做到这一点(可能采用完全不同的方法)?
答案 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|
+----------+---+---+---+---+---+