将多个(任意数量)火花 DataFrame 列连接成一个“|”分隔字符串
Posted
技术标签:
【中文标题】将多个(任意数量)火花 DataFrame 列连接成一个“|”分隔字符串【英文标题】:Concatenating multiple (any number) spark DataFrame columns into one "|" deliminated string 【发布时间】:2019-04-30 17:44:24 【问题描述】:我有一个 DataFrame 和一个作为字符串的列列表,我需要在原始数据框中添加一个列,该列是 |
分隔的值列表,其中 null
变成字符串 @987654323 @
这是我目前拥有的代码:
def mergeColumns(cols: Array[String], df: DataFrame, newName: String): DataFrame =
val dfColumns = cols.map( columnName => df(columnName) )
df.withColumn(newName, concatenate(array(dfColumns: _*), lit("|")))
val concatenate: UserDefinedFunction = udf( (columns: Seq[Any], separator: String) =>
columns.map(
case null => "null"
case default => default.toString
).mkString(separator)
)
并且该代码有效,但前提是所有提供的列都属于同一类型,并且我当前的计划是尝试将它们全部转换为 String 类型。所以我有两个问题:
1)一般来说有没有更好的方法来做到这一点?
2)如果没有,我如何将所有dfColumns
列转换为字符串?
【问题讨论】:
【参考方案1】:您可以在 Row
类上使用 mkString
来做到这一点:
val df =Seq(
("a", "b",Option.empty[String])
).toDF("Col1","Col2","Col3")
val makeString = udf((r : Row) => r.mkString("|"))
df.withColumn("newCol",makeString(struct("*")))
.show()
给予
+----+----+----+--------+
|Col1|Col2|Col3| newCol|
+----+----+----+--------+
| a| b|null|a|b|null|
+----+----+----+--------+
【讨论】:
如果我只想要这些列的一个子集怎么办,比如Col2
和Col3
。我仍然想要原来的列,所以架构仍然是Col1, Col2, Col3, newCol
我找到了问题的答案,只需使用struct(columns: _*)
代替struct("*")
,其中columns
是原帖中的dfColumns
。【参考方案2】:
尝试使用 fill null values
和 concat_ws
函数。
前:
val df =Seq(
("a", "b",Option.empty[String]))
.toDF("Col1","Col2","Col3")
df.na.fill("null")
.withColumn("cn_ws",concat_ws("|", array("*")))
.show(false)
结果:
+----+----+----+--------+
|Col1|Col2|Col3|cn_ws |
+----+----+----+--------+
|a |b |null|a|b|null|
+----+----+----+--------+
更新:
将所有列投射到 "string"
df.na.fill("null")
.withColumn("cn_ws",
concat_ws("|", array(df.columns.map(c => col(c).cast(StringType)): _*)))
.show(false)
【讨论】:
根据文档:Concatenates multiple input string columns together into a single string column, using the given separator.
有没有办法确保所有列都是字符串列?
@JaredDuPont,请检查我的更新答案..! :-)以上是关于将多个(任意数量)火花 DataFrame 列连接成一个“|”分隔字符串的主要内容,如果未能解决你的问题,请参考以下文章
如何在 spark DataFrame 中将多个浮点列连接到一个 ArrayType(FloatType()) 中?