首页 > 解决方案 > 从值动态创建列

问题描述

在我们的项目中,我们使用一个ETL框架(内置PySpark),它接受Spark-sql语句来从源转换数据并加载Hive外部表。

现在,我需要读取一个表,然后选择一列的唯一值,然后动态创建一个包含那么多列的 Hive 表。

例如,考虑下表。

第 1 天:

qstn_mstr:

prsnid | qstn 
1 | satisfactory
2 | survey 
3 | review

目标表结构:

prsnid | satisfactory | survey | review

第 1 天:在上面的示例中,列中有3唯一值qstns,因此输出表是使用这些3值作为列创建的。

第 2 天:说不。qstn表中列中唯一值的Qstn_mster数量更改为 5(可以增加或减少),这反过来会影响编号。目标表中的列,现在需要保存5列。

第 2 天:

qstn_mstr:

prsnid | qstn 
1 | satisfactory
2 | survey 
3 | review 
4 | validity
5 | vote

目标表结构:

prsnid | satisfactory | survey | review | validity | vote

因此,每天,目标表结构都会动态变化。

使用带有 Hive 表的 PySpark 环境设计/建模此类要求的最佳方法是什么?

请分享你的想法。

标签: hivedata-modelingpyspark-sql

解决方案


如果意图是在每一列上应用一些计算,比如计数或不同等。那么可以使用pivot

例子:

df = sqlContext.createDataFrame(
    [[1, "satisfactory"],
     [2, "survey"],
     [3, "review"],
     [4, "validity"],
     [5, "vote"],], 
    ["prsn_id", "qstn"])

(df
.groupBy(["prsn_id"])
.pivot("qstn")
.agg({"prsn_id": "count"})
.fillna(0)
.orderBy(["prsn_id"])
.show())

输出:

+-------+------+------------+------+--------+----+
|prsn_id|review|satisfactory|survey|validity|vote|
+-------+------+------------+------+--------+----+
|      1|     0|           1|     0|       0|   0|
|      2|     0|           0|     1|       0|   0|
|      3|     1|           0|     0|       0|   0|
|      4|     0|           0|     0|       1|   0|
|      5|     0|           0|     0|       0|   1|
+-------+------+------------+------+--------+----+

但是,如果目的只是创建这些列并说,现在将它们设置为 0 那么:

column_list = [psf.lit(0).alias(col[0]) 
               for col in 
               df.select("qstn")
               .distinct().collect()]


df.select(["prsn_id"] + column_list).show()

输出:

+-------+----+--------+------+------+------------+
|prsn_id|vote|validity|survey|review|satisfactory|
+-------+----+--------+------+------+------------+
|      1|   0|       0|     0|     0|           0|
|      2|   0|       0|     0|     0|           0|
|      3|   0|       0|     0|     0|           0|
|      4|   0|       0|     0|     0|           0|
|      5|   0|       0|     0|     0|           0|
+-------+----+--------+------+------+------------+

推荐阅读