我正在使用Spark 2.2.0和Scala 2.11.8将数据从HDFS读入DataFrame:
val df = spark.read.text(outputdir)
df.show()
我看到了这个结果:
+--------------------+
| value|
+--------------------+
|(4056,{community:...|
|(56,{community:56...|
|(2056,{community:...|
+--------------------+
如果我运行df.head()
,我会看到有关每行结构的更多详细信息:
[(4056,{community:1,communitySigmaTot:1020457,internalWeight:0,nodeWeight:1020457})]
我想获得以下输出:
+---------+----------+
| id | value|
+---------+----------+
|4056 |1 |
|56 |56 |
|2056 |20 |
+---------+----------+
我该怎么办?我尝试使用.map(row => row.mkString(","))
,
但我不知道如何提取数据。
答案 0 :(得分:2)
问题是您将数据作为单个字符串列获取。问题中没有真正指定数据格式(理想情况下它会像JSON一样),但根据我们所知,我们可以使用正则表达式来提取左侧(id)和社区字段的数字:
val r = """\((\d+),\{.*community:(\d+).*\}\)"""
df.select(
F.regexp_extract($"value", r, 1).as("id"),
F.regexp_extract($"value", r, 2).as("community")
).show()
答案 1 :(得分:1)
一堆正则表达式应该可以提供所需的结果。
df.select(
regexp_extract($"value", "^\\(([0-9]+),.*$", 1) as "id",
explode(split(regexp_extract($"value", "^\\(([0-9]+),\\{(.*)\\}\\)$", 2), ",")) as "value"
).withColumn("value", split($"value", ":")(1))
答案 2 :(得分:1)
如果您的数据始终采用以下格式
(4056,{community:1,communitySigmaTot:1020457,internalWeight:0,nodeWeight:1020457})
然后,您只需使用split
和regex_replace
内置函数即可获得所需的输出dataframe
import org.apache.spark.sql.functions._
df.select(regexp_replace((split(col("value"), ",")(0)), "\\(", "").as("id"), regexp_replace((split(col("value"), ",")(1)), "\\{community:", "").as("value") ).show()
我希望答案很有帮助