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 |
#+---------+---+----+-----+---+
注意:transfrom
和 map_from_entries
函数仅适用于 Spark 2.4+
我的 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}
.
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 |
#+---------+---+----+-----+---+
注意:transfrom
和 map_from_entries
函数仅适用于 Spark 2.4+