Dataframe regexp_extract 值来自数组之类的字符串

Dataframe regexp_extract values from string like array

我的 DataFrame 如下所示:

StudentID          Marks
100                ["20", "25.5", "40.23", "50"]
200                ["30", "20", "25", "40"]
300                ["20", "25", "50", "35"]

我需要提取数组中的 marks 并创建一个新的 DataFrame。但是,我无法提取超出 DF 中第二个值的内容(不知道如何通过正则表达式 ([0-9]+)(?:\.[0-9]+){3}.

select 所有标记
df1.select(regexp_extract('StudentID', '(\w+)(,)', 1).alias("C1"), 
             regexp_extract('Marks', '([0-9]+)(?:\.[0-9]+){3}', 0).alias("C2"))

最终,需要创建一个具有以下格式的新 DataFrame:

StudentID  C1    C2    C3     C4
100        20    25.5  40.23  50
200        30    20    25     40
300        20    25    50     35

提前致谢。

您可以拆分字符串,然后使用 element_at 将子字符串拉到单独的列中:

df1.withColumn("marks_array", split( regexp_replace(col("Marks"), "\[|\]|\"", ""), ",")  )
      .withColumn("C1", element_at(col("marks_array"), 1))
      .withColumn("C2", element_at(col("marks_array"), 2))
      .withColumn("C3", element_at(col("marks_array"), 3))
      .withColumn("C4", element_at(col("marks_array"), 4))
      .drop("marks_array", "Marks")
      .show(false)
+---------+---+-----+------+---+
|StudentID|C1 |C2   |C3    |C4 |
+---------+---+-----+------+---+
|100      |20 | 25.5| 40.23| 50|
|200      |30 | 20  | 25   | 40|
|300      |20 | 25  | 50   | 35|
+---------+---+-----+------+---+

您可以使用 from_json 将字符串列 Marks 转换为字符串数组。然后获取数组的元素以创建每一列。

但是,如果您不知道数组的大小,您可以使用 transform 函数将其转换为地图,然后展开地图并旋转以获得所需的输出。

transform_expr = """transform(from_json(Marks, 'array<string>'), 
                              (x, i) -> struct(concat('C', i+1), x)
                             )
                 """

df.select(col("*"), explode(map_from_entries(expr(transform_expr)))) \
  .groupBy("StudentID").pivot("key").agg(first("value")) \
  .show()

#+---------+---+----+-----+---+
#|StudentID|C1 |C2  |C3   |C4 |
#+---------+---+----+-----+---+
#|100      |20 |25.5|40.23|50 |
#|200      |30 |20  |25   |40 |
#|300      |20 |25  |50   |35 |
#+---------+---+----+-----+---+

注意:transfrommap_from_entries 函数仅适用于 Spark 2.4+