将半结构化字符串转换为pyspark数据框

时间:2019-08-22 22:36:18

标签: regex pyspark pyspark-sql

我得到了以下数据框

+---+--------------------------------------+
| id|                                 score|
+---+--------------------------------------+
|  1|(math, 90)(physics, 87)(chemistry, 82)|
+---+--------------------------------------+
|  2|                        (computer, 84)|
+---+--------------------------------------+
|  3|                                  null|
+---+--------------------------------------+

其中score列的类型为str。 我想像下面这样将str转换成array<str>

+---+--------------------------------------------+
| id|                                       score|
+---+--------------------------------------------+
|  1|['math, 90', 'physics, 87', 'chemistry, 82']|
+---+--------------------------------------------+
|  2|                            ['computer, 84']|
+---+--------------------------------------------+
|  3|                                        null|
+---+--------------------------------------------+

因此,基本上它将字符串拆分为数组并删除所有括号。

我正在参考this问题,但是我不确定要使用的正确正则表达式是什么。

感谢并感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

这应该仅使用Spark SQL函数即可为您提供所需的输出。

仅使用Spark SQL函数进行操作有点费时。 UDF可能会提供更清晰的结果,但不能确定对性能的影响。

from pyspark.sql import functions as F

testDF = spark.createDataFrame([
    (1, "(math, 90)(physics, 87)(chemistry, 82)"),
    (2, "(computer, 84)"),
    (3, "null")
], ["id", "score"])

testDF.select('id', F.split('score', '[)][(]').alias('score'))\
    .select('id', F.explode('score').alias('score'))\
    .select('id', F.regexp_replace('score', '[)]|[(]', '').alias('score'))\
    .groupBy('id')\
    .agg(F.collect_list("score").alias("score"))\
    .orderBy('id')\
    .show()

请注意,数组/列表元素周围的引号不会出现。但是,如果您运行collect()而不是show(),则可以看到它。