首页 > 解决方案 > 将多列从行旋转到列

问题描述

我有一个 PySpark 数据框,如下所示:

| id   | name   | policy     | payment_name | count |
|------|--------|------------|--------------|-------|
| 2    | two    | 0          | Hybrid       | 58    |
| 2    | two    | 1          | Hybrid       | 2     |
| 5    | five   | 1          | Excl         | 13    |
| 5    | five   | 0          | Excl         | 70    |
| 5    | five   | 0          | Agen         | 811   |
| 5    | five   | 1          | Agen         | 279   |
| 5    | five   | 1          | Hybrid       | 600   |
| 5    | five   | 0          | Hybrid       | 2819  |

我想组合policypayment_name成为具有相应计数的列(减少到每行id)。

输出如下所示:

| id | name | no_policy_hybrid | no_policy_excl | no_policy_agen | policy_hybrid | policy_excl | policy_agen |
|----|------|------------------|----------------|----------------|---------------|-------------|-------------|
| 2  | two  | 58               | 0              | 0              | 2             | 0           | 0           |
| 5  | five | 2819             | 70             | 811            | 600           | 13          | 279         |

在没有组合的情况下,我们可以将其默认为 0,即id2 没有包含payment_nameExcl 的组合,因此在示例输出中将其设置为 0。

标签: pythonpysparkpivottranspose

解决方案


要旋转表格,您首先需要一个分组列来组合policypayment_name

df = df.withColumn("groupingCol", udf("{}_{}".format)("policy", "payment_name"))

当您拥有它时,您可以按id and 名称列分组并旋转分组列。

df.groupBy("id", "name").pivot("groupingCol").agg(F.max("count"))

那应该返回正确的表列。

+---+----+------+------+--------+------+------+--------+
| id|name|0_Agen|0_Excl|0_Hybrid|1_Agen|1_Excl|1_Hybrid|
+---+----+------+------+--------+------+------+--------+
|  5|five|   811|    70|    2819|   279|    13|     600|
|  2| two|  null|  null|      58|  null|  null|       2|
+---+----+------+------+--------+------+------+--------+

要获得与示例中相同的列名,您可以先将策略列的内容更改为policyno_policy如下所示:

df = df.withColumn("policy", when(col("policy") == 1, "policy").otherwise("no_policy"))

这是您将缺失值替换为的方式0

df.na.fill(0)

推荐阅读