我是Spark的新手,我有一个包含4列的Apache SparkSQL DataFrame df
,具有以下架构:
root
|-- _id: string (nullable = false)
|-- _title: string (nullable = false)
|-- _published-at: date (nullable = false)
|-- p: array (nullable = true)
| |-- element: string (containsNull = true)
df
包含大量(一百万左右)新闻文章,每条记录的列包含:唯一ID(_id),标题(_title),发布日期(_published-at)和String数组每篇文章(p)中的 paragraphs 文本。
我现在想将“ p”列从文章段落的当前格式Array[String]
转换为文章全文的融合String
,其中转换是段落的简单映射元素之间用空格(“”)串联,从而在String
中添加了新的第五df
列。即像这样的东西:
df.withColumn(df.(col"p").map(_.mkString(" ")).alias("fullarticle"))
这不起作用。但是,这似乎是一个微不足道的问题,但是我一定错了。在Spark的functions
包中,可以找到许多功能,但是似乎没有合适的功能。我必须以某种方式使用“用户定义函数”(UDF)吗?最好是避免这种情况。
可以通过以下操作将其转换为String
,从而产生一个新的Dataset[String] dsFullArticles
:
dsFullArticles = df.select(col("p").as[Array[String]]).map(_.mkString(" ")).alias("fullarticle")
(似乎需要.as[Array[String]]
来解开实际上包裹了“ p”列中每个WrappedArray
元素的Array[String]
)。但是如何代替将dsFullArticles
作为新的列附加到df
?
此后,我还想在“全文”列中找到每篇文章的最长单词的长度,并将其作为第六列添加到df
中:
// Split each article in an array of its words
val dsFullArticlesArrayOfWords = dsFullArticles.map(s => s.split(" "))
// Find number of characters of longest word in article, 0 if article is empty
val dsMaxWordLength =
dsFullArticlesArrayOfWords.map(s => (s.map(w => w.length()) match {
case x if x.isEmpty => 0
case x => x.max
}))
上面的代码也可以正常工作,产生Dataset[int]
,但是,如何类似地将其作为列添加到df
中呢?同样的问题在这里。当所有内容都在同一DataFrame df
中时,很容易进行各种SQL选择,过滤等。
答案 0 :(得分:0)
您可以使用concat_ws功能:
concat_ws(sep,[str | array(str)] +)-返回由Sep分隔的字符串的串联。
在您的情况下:
df.withColumn("fullarticle", concat_ws(" ",col("p")))