Непивот в искро-sql/pyspark

У меня под рукой есть постановка задачи, в которой я хочу отключить таблицу в spark-sql/pyspark. Я просмотрел документацию и увидел, что есть поддержка только для pivot, но пока нет поддержки un-pivot. Есть ли способ, которым я могу достичь этого?

Пусть моя исходная таблица будет выглядеть так:

Let my initial table look like this

когда я поворачиваю это в pyspark, используя нижеприведенную команду:

df.groupBy("A").pivot("B").sum("C")

Я получаю это в качестве вывода:

After pivot table looks like this

Теперь я хочу отменить поворотную таблицу. В общем, эта операция может/не может привести к исходной таблице на основе того, как я повернул исходную таблицу.

Spark-sql на данный момент не предоставляет встроенную поддержку для разворачивания. Есть ли способ, которым я могу достичь этого?

Ответ 1

Вы можете использовать встроенную функцию стека, например, в Scala:

scala> val df = Seq(("G",Some(4),2,None),("H",None,4,Some(5))).toDF("A","X","Y", "Z")
df: org.apache.spark.sql.DataFrame = [A: string, X: int ... 2 more fields]

scala> df.show
+---+----+---+----+
|  A|   X|  Y|   Z|
+---+----+---+----+
|  G|   4|  2|null|
|  H|null|  4|   5|
+---+----+---+----+


scala> df.select($"A", expr("stack(3, 'X', X, 'Y', Y, 'Z', Z) as (B, C)")).where("C is not null").show
+---+---+---+
|  A|  B|  C|
+---+---+---+
|  G|  X|  4|
|  G|  Y|  2|
|  H|  Y|  4|
|  H|  Z|  5|
+---+---+---+

Или в pyspark:

In [1]: df = spark.createDataFrame([("G",4,2,None),("H",None,4,5)],list("AXYZ"))

In [2]: df.show()
+---+----+---+----+
|  A|   X|  Y|   Z|
+---+----+---+----+
|  G|   4|  2|null|
|  H|null|  4|   5|
+---+----+---+----+

In [3]: df.selectExpr("A", "stack(3, 'X', X, 'Y', Y, 'Z', Z) as (B, C)").where("C is not null").show()
+---+---+---+
|  A|  B|  C|
+---+---+---+
|  G|  X|  4|
|  G|  Y|  2|
|  H|  Y|  4|
|  H|  Z|  5|
+---+---+---+