【问题标题】:Convert Spark DF to a DS with different fields names将 Spark DF 转换为具有不同字段名称的 DS
【发布时间】:2021-12-16 11:49:12
【问题描述】:

我想将 Spark 数据帧转换为具有不同字段名称的 POJO 数据集。我有一个字段的数据框:namedate_of_birth,它们的类型是StringTypeDateType

还有一个 POJO:

public class Person implements Serializable {
    private String name;
    private Date dateOfBirth;
}

将其成功转换为数据集,代码如下:

Encoder<Person> personEncoder =  Encoders.bean(Person.class); 
Dataset<Person> personDS = result.as(personEncoder);
List<Person> personList = personDS.collectAsList();

仅当我在此之前将数据框的列名更改为 Person POJO 的列名。有什么方法可以告诉 Spark 在 POJO 端的字段之间进行映射?

我想到了 Gson 的@SerializedName(“date_of_birth”),但没有任何影响。

【问题讨论】:

    标签: java apache-spark apache-spark-sql pojo apache-spark-dataset


    【解决方案1】:

    如果您有名称映射,例如在地图中,您可以在将数据框转换为数据集之前使用它重命名列。

    可以这样写:

    // I create the map, but it could be read from a config file for instance
    Map<String, String> nameMapping = new java.util.HashMap<>();
    nameMapping.put("id", "name");
    nameMapping.put("date", "dateOfBirth");
    
    Column[] renamedColumns = nameMapping
                    .entrySet()
                    .stream()
                    .map(x -> col(x.getKey()).alias(x.getValue()))
                    .collect(Collectors.toList())
                    .toArray(new Column[0]);
    
    result.select(renamedColumns).as(personEncoder)
    

    【讨论】:

      【解决方案2】:

      我不知道具体的注释。但是,这是我的解决方法。

      我会创建一个具有我想要的形状的特定数据框,然后将其导出。

      看起来像:

      Dataset<Row> exportDf = df
          .withColumn("dateOfBirth",
              col("date_of_birth").cast(DataTypes.StringType))
          .drop("date_of_birth");
      

      我写的完整例子可以在这里找到:https://github.com/jgperrin/net.jgp.labs.spark/tree/master/src/main/java/net/jgp/labs/spark/l999_scrapbook/l002

      注意事项:

      • 我假设您代码中的resultDataset&lt;Row&gt;
      • 我使用字符串作为您的日期,因为 Spark 在将日期转换为 POJO 中的字符串时有点棘手。如果您在此问题上需要特别帮助,请创建另一个 SO 问题,我会很乐意查看。

      【讨论】:

      • 感谢您的努力!这个解决方案不太合适,因为我希望转换是动态的,所以我可以为 DF 和 POJO 添加一个列和一个字段,并且它可以在不接触转换代码的情况下工作。
      • 我明白了...不过要小心数据类型,它们可能会在转换过程中欺骗您...尤其是日期!
      猜你喜欢
      • 1970-01-01
      • 2022-01-20
      • 2018-11-30
      • 2017-05-17
      • 1970-01-01
      • 2015-11-19
      • 1970-01-01
      • 1970-01-01
      • 2016-02-06
      相关资源
      最近更新 更多