【问题标题】:Spark : remove keys of a map columnSpark:删除地图列的键
【发布时间】:2021-06-07 12:34:35
【问题描述】:

我有一个数据集 ds,其中包含一个映射列 userInfo,它有 3 个键:

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

现在我想在我的新数据集dsNew 中也有这个地图列(例如dsNew = ds.withColumn(...)),但删除键“电话”。执行此操作的最佳性能方式是什么?

请注意,这只是一个简化的示例,实际上这个映射列有很多键值对,我想删除它的一个子集。

谢谢。

【问题讨论】:

标签: java scala apache-spark apache-spark-sql


【解决方案1】:

除了我使用UDF的链接答案之外,如果您的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'))"))

【讨论】:

    【解决方案2】:

    如果您只有 3 个键,则通过获取要保留的 2 个键来创建新地图很简单:

    val dsNew = ds.withColumn(
      "userInfo",
      map(lit("name"), $"userInfo"("name"), lit("age"), $"userInfo"("age"))
    )
    
    dsNew.show
    //+------------------------+
    //|userInfo                |
    //+------------------------+
    //|[name -> Tom, age -> 52]|
    //+------------------------+
    

    地图过滤仅在另一个答案中指出的 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")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-16
      • 1970-01-01
      • 2017-12-27
      • 1970-01-01
      • 1970-01-01
      • 2020-02-26
      • 2022-10-14
      • 2021-09-05
      相关资源
      最近更新 更多