在Spark中将字符串转换为数据帧的四个不同列

时间:2019-04-21 17:57:15

标签: scala apache-spark

每个人,我都是Spark的新手(说实话,编程),并且在以下情况下我需要一些帮助。我的输入文件包含以下格式的数据。     端口号-用户ID“ GET \ ..”     端口号-用户ID“ GET \ ..”

对于每个用户,我们将有两行数据。每行仅包含一个字符串(包括空格),但没有适当的定界符

示例输入:

192.167.56.1-45195 “ GET \docsodb.sp.ip \..”
192.167.56.1-45195 “ GET \https://<url> \..”
238.142.23.5-24788 “ GET \docsodb.sp.ip \..”
238.142.23.5-24788 “ GET \ https://<url>  \..”
30.169.77.213-16745 “ GET \docsodb.sp.ip \..”
30.169.77.213-16745 “ GET \ https://<url> \..”

对于上述数据,我需要以以下格式输出,可能是一个数据框。

Portnumber      UserID  URL             division_string
192.167.56.1    45195   https://<url>   docsodb.sp.ip
238.142.23.5    24788   https://<url>   docsodb.sp.ip
30.169.77.213   16745   https://<url>   docsodb.sp.ip

我们可以通过RDD转换来实现这一点,还是必须使用Spark SQL(通过SQL查询)。另外,如果这两种方法都能实现,那么请您说明哪种方法更好?

1 个答案:

答案 0 :(得分:0)

让我们准备数据并运行spark-shell

cat <<-EOF >in
192.167.56.1-45195 “ GET \docsodb.sp.ip \..”
192.167.56.1-45195 “ GET \https://<url> \..”
238.142.23.5-24788 “ GET \docsodb.sp.ip \..”
238.142.23.5-24788 “ GET \ https://<url>  \..”
30.169.77.213-16745 “ GET \docsodb.sp.ip \..”
30.169.77.213-16745 “ GET \ https://<url> \..”
EOF

spark-shell

现在,在spark-shell中,我们将数据从文本文件加载到DataFrame中,然后根据正则表达式捕获组进行解析,最后按Portnumber和UserId分组,以在同一行上同时获得Division_string和URL,所有这些都使用DataFrame API。

import spark.implicits._

// Load data
val df = spark.read.format("text").load("in")

// Regexp to parse input line
val re = """([\d\.]+)-(\d+) “ GET \\ ?([^\s]+)"""

// Transform
df.select(regexp_extract('value, re, 1).as("Portnumber"),
          regexp_extract('value, re, 2).as("UserId"),
          regexp_extract('value, re, 3).as("URL_or_div"))
  .groupBy('Portnumber, 'UserId)
  .agg(max(when('URL_or_div.like("https%"), 'URL_or_div)).as("URL"),
       max(when('URL_or_div.like("docsodb%"), 'URL_or_div)).as("division_stringL"))
  .show

+-------------+------+-------------+---------------+
|   Portnumber|UserId|          URL|division_string|
+-------------+------+-------------+---------------+
|30.169.77.213| 16745|https://<url>|  docsodb.sp.ip|
| 192.167.56.1| 45195|https://<url>|  docsodb.sp.ip|
| 238.142.23.5| 24788|https://<url>|  docsodb.sp.ip|
+-------------+------+-------------+---------------+

回答最后一个问题比RDD操作优先使用DataFrame API或Spark SQL,除非您需要对处理进行低级控制。有关更多信息,请参见here