如何在 Map 类型的数据框中获取一列并创建一个字符串,该字符串只是 Map 列的键/值
Posted
技术标签:
【中文标题】如何在 Map 类型的数据框中获取一列并创建一个字符串,该字符串只是 Map 列的键/值【英文标题】:How can I take a column in a dataframe that is a Map type and create a string that is just the key/value of the Map column 【发布时间】:2019-08-06 00:01:10 【问题描述】:我有兴趣在我的数据框中获取一个名为 mapColumn 的列
+-------------------+
| mapColumn |
+-------------------+
| Map(KEY -> VALUE) |
+-------------------+
并创建一个 stringColumn,它只是 Map 列的键和值,其中值为“KEY,VALUE”:
+-------------------+
| stringColumn |
+-------------------+
| KEY,VALUE |
+-------------------
我尝试创建一个 UDF 来传递这个值,如下所示:
var getStringColumn = udf(mapToString _)
df.withColumn("stringColumn,
when(col(mapColumn).isNotNull,
getStringColumn(col(mapColumn)))
.otherwise(lit(null: String)))
def mapToString(row: Row): String =
if (null == row || row.isNullAt(FirstItemIndex))
return null
return row.getValuesMap[Any](row.schema.fieldNames).mkString(",")
我不断收到以下错误:
执行用户定义函数失败($anonfun$1: (map) => string) 原因:java.lang.ClassCastException:scala.collection.immutable.Map$Map1 不能转换为 org.apache.spark.sql.Row
【问题讨论】:
【参考方案1】:不需要UDF。一种方法是将explode
Map
列转换为扁平的key
和value
列,并将concat
键值元素相应地转换为String
s:
val df = Seq(
(10, Map((1, "a"), (2, "b"))),
(20, Map((3, "c")))
).toDF("id", "map")
df.
select($"id", explode($"map")).
withColumn("kv_string", concat($"key".cast("string"), lit(","), $"value")).
show
// +---+---+-----+---------+
// | id|key|value|kv_string|
// +---+---+-----+---------+
// | 10| 1| a| 1,a|
// | 10| 2| b| 2,b|
// | 20| 3| c| 3,c|
// +---+---+-----+---------+
【讨论】:
以上是关于如何在 Map 类型的数据框中获取一列并创建一个字符串,该字符串只是 Map 列的键/值的主要内容,如果未能解决你的问题,请参考以下文章