phi*_*thy 4 python url dataframe apache-spark pyspark
假设我有一个充满 URL 的列,如下所示:
+------------------------------------------+
|url |
+------------------------------------------+
|https://www.example1.com?param1=1¶m2=a|
|https://www.example2.com?param1=2¶m2=b|
|https://www.example3.com?param1=3¶m2=c|
+------------------------------------------+
Run Code Online (Sandbox Code Playgroud)
从该列中提取 URL 参数并将它们作为列添加到数据框中以生成以下内容的最佳方法是什么?
+-------------------------------------------+---------------+
| url| param1| param2|
+-------------------------------------------+---------------+
|https://www.example1.com?param1=1¶m2=a | 1| a|
|https://www.example2.com?param1=2¶m2=b | 2| b|
|https://www.example3.com?param1=3¶m2=c | 3| c|
|etc... | etc...| etc...|
+-------------------------------------------+---------------+
Run Code Online (Sandbox Code Playgroud)
我可以想到两种可能的方法来做到这一点,使用functions.regexp_extract
pyspark 库或使用标准库中的urllib.parse.parse_qs
and 。urllib.parse.urlparse
前一种解决方案使用正则表达式,这是一种从字符串中提取参数的挑剔方法,但后者需要包装在 UDF 中才能使用。
+------------------------------------------+
|url |
+------------------------------------------+
|https://www.example1.com?param1=1¶m2=a|
|https://www.example2.com?param1=2¶m2=b|
|https://www.example3.com?param1=3¶m2=c|
+------------------------------------------+
Run Code Online (Sandbox Code Playgroud)
正则表达式解决方案:
+-------------------------------------------+---------------+
| url| param1| param2|
+-------------------------------------------+---------------+
|https://www.example1.com?param1=1¶m2=a | 1| a|
|https://www.example2.com?param1=2¶m2=b | 2| b|
|https://www.example3.com?param1=3¶m2=c | 3| c|
|etc... | etc...| etc...|
+-------------------------------------------+---------------+
Run Code Online (Sandbox Code Playgroud)
UDF解决方案:
from pyspark.sql import *
from pyspark.sql import functions as fn
df = spark.createDataFrame(
[
("https://www.example.com?param1=1¶m2=a",),
("https://www.example2.com?param1=2¶m2=b",),
("https://www.example3.com?param1=3¶m2=c",)
],
["url"]
)
Run Code Online (Sandbox Code Playgroud)
我想使用像这样的库的多功能性,urllib
但也希望在 pyspark 函数中编写它的可优化性。有没有比我迄今为止尝试过的两种方法更好的方法?
您可以parse_url
在 SQL 表达式内使用expr
。
parse_url
可以使用第三个参数来指定我们要从 URL 中提取的键 (param):
df.selectExpr("*", "parse_url(url,'QUERY', 'param1')").show()
+------------------------------------------+------+
|url |param1|
+------------------------------------------+------+
|https://www.example2.com?param1=2¶m2=b|2 |
|https://www.example.com?param1=1¶m2=a |1 |
|https://www.example3.com?param1=3¶m2=c|3 |
+------------------------------------------+------+
Run Code Online (Sandbox Code Playgroud)
如果要将所有查询参数提取为新列,而无需指定其名称,则可以首先解析 URL,然后拆分和爆炸以获取参数及其值,最后通过透视将每个参数获取为一列。
import pyspark.sql.functions as F
df.withColumn("parsed_url", F.explode(F.split(F.expr("parse_url(url, 'QUERY')"), "&"))) \
.withColumn("parsed_url", F.split("parsed_url", "=")) \
.select("url",
F.col("parsed_url").getItem(0).alias("param_name"),
F.col("parsed_url").getItem(1).alias("value")
) \
.groupBy("url") \
.pivot("param_name") \
.agg(F.first("value")) \
.show()
Run Code Online (Sandbox Code Playgroud)
给出:
+------------------------------------------+------+------+
|url |param1|param2|
+------------------------------------------+------+------+
|https://www.example2.com?param1=2¶m2=b|2 |b |
|https://www.example.com?param1=1¶m2=a |1 |a |
|https://www.example3.com?param1=3¶m2=c|3 |c |
+------------------------------------------+------+------+
Run Code Online (Sandbox Code Playgroud)
正如 @jxc 在评论中建议的,另一个解决方案是使用str_to_map
函数:
df.selectExpr("*", "explode(str_to_map(split(url,'[?]')[1],'&','='))") \
.groupBy('url') \
.pivot('key') \
.agg(F.first('value'))
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
8489 次 |
最近记录: |