spark:删除Map列的键

hiz5n14c  于 2021-07-12  发布在  Spark
关注(0)|答案(2)|浏览(265)

我有一个数据集 ds 包含Map列 userInfo 有3个键:

{"name":"Tom", "age":"52", "phone":"45124"}

现在我想在我的新数据集 dsNew 也有这个Map栏(例如。 dsNew = ds.withColumn(...) ),但删除键“phone”。最好的方法是什么?
请注意,这只是一个简化的示例,实际上这个map列有许多键值对,我想删除其中的一个子集。
谢谢。

ki1q1bka

ki1q1bka1#

除了我使用自定义项的链接答案外,如果您的spark版本>=3.0,您还可以使用 map_filter :

dsNew = ds.withColumn("userInfo", expr("map_filter(userInfo, (k, v) -> k != 'phone')"))

如果要删除多个密钥,可以使用 not in :

dsNew = ds.withColumn("userInfo", expr("map_filter(userInfo, (k, v) -> k not in ('phone', 'phone2'))"))
mklgxw1f

mklgxw1f2#

如果只有3个关键点,则通过获取要保留的2个关键点来创建新Map非常简单:

val dsNew = ds.withColumn(
  "userInfo",
  map(lit("name"), $"userInfo"("name"), lit("age"), $"userInfo"("age"))
)

dsNew.show
//+------------------------+
//|userInfo                |
//+------------------------+
//|[name -> Tom, age -> 52]|
//+------------------------+

Map过滤仅在另一个答案中指出的spark版本3之后才可用。在spark 2.4中,您可以获取关键点并使用数组函数对其进行过滤,然后使用 map_from_arrays 功能:

val dsNew = ds.withColumn(
    "filtered_keys",
    expr("filter(map_keys(userInfo), x -> x <> 'phone')")
  ).withColumn(
    "userInfo",
    map_from_arrays(
      $"filtered_keys",
      expr("transform(filtered_keys, x -> userInfo[x])")
    )
  ).drop("filtered_keys")

相关问题