将 Spark DF 转换为具有不同字段名称的 DS
Convert Spark DF to a DS with different fields names
我想将 Spark 数据帧转换为具有不同字段名称的 POJO 数据集。我有一个字段的数据框:name
、date_of_birth
,它们的类型是 StringType
、DateType
。
还有一个 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”)
但是没有影响。
如果您有名称映射,比如在地图中,您可以在将数据框转换为数据集之前使用它来重命名列。
可以这样写:
// 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)
我不知道具体的注释。但是,这是我的解决方法。
我会创建一个具有我想要的形状的特定数据框,然后将其导出。
看起来像:
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。
备注:
- 我假设您代码中的
result
是 Dataset<Row>
。
- 我使用字符串作为您的日期,因为 Spark 对于将日期转换为 POJO 中的字符串有点敏感。如果您需要专门针对此问题的帮助,请创建另一个 SO 问题,我会很乐意查看。
我想将 Spark 数据帧转换为具有不同字段名称的 POJO 数据集。我有一个字段的数据框:name
、date_of_birth
,它们的类型是 StringType
、DateType
。
还有一个 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”)
但是没有影响。
如果您有名称映射,比如在地图中,您可以在将数据框转换为数据集之前使用它来重命名列。
可以这样写:
// 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)
我不知道具体的注释。但是,这是我的解决方法。
我会创建一个具有我想要的形状的特定数据框,然后将其导出。
看起来像:
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。
备注:
- 我假设您代码中的
result
是Dataset<Row>
。 - 我使用字符串作为您的日期,因为 Spark 对于将日期转换为 POJO 中的字符串有点敏感。如果您需要专门针对此问题的帮助,请创建另一个 SO 问题,我会很乐意查看。