我有一個具有以下架構的資料框:
StructType currentSchema = new StructType(new StructField[]{
new StructField("age", DataTypes.StringType, false, Metadata.empty()),
new StructField("grade", DataTypes.StringType, false, Metadata.empty()),
new StructField("dateOfBirth", DataTypes.StringType, false, Metadata.empty())
});
我想立即將它(不指定每一列)轉換為以下模式:
StructType newSchema = new StructType(new StructField[]{
new StructField("age", DataTypes.IntegerType, false, Metadata.empty()),
new StructField("grade", DataTypes.IntegerType, false, Metadata.empty()),
new StructField("dateOfBirth", DataTypes.DateType, false, Metadata.empty())
});
有沒有辦法做這樣的df.convert(newSchema)操作?
uj5u.com熱心網友回復:
由于 DataFrame 是不可變的,因此您必須創建新的 DataFrame 來更改架構。為此,請執行以下方法之一:
一世:
Dataset<Row> ndf = df.select(col("age").cast(DataTypes.IntegerType),
col("grade").cast(DataTypes.IntegerType),
col("dateOfBirth").cast(DataTypes.DateType));
ndf.printSchema();
二:
或(我只是為年齡列做的):
Dataset<Row> ndf = df.withColumn("new_age", df.col("age").cast(DataTypes.IntegerType)).drop("age");
ndf.printSchema();
三:
最后但并非最不重要的一點是,使用 map 函式進行操作并同時更改型別:
Dataset<Row> df2 = df.map(new MapFunction<Row, Row>() {
@Override
public Row call(Row row) throws Exception {
return RowFactory.create((int)row.getString(0),
(int)row.getString(1),
(date)row.getString(2));
}
}, RowEncoder.apply(newSchema));
df2.printSchema();
在此方法中,如果強制轉換(int)不起作用,請使用Integer.Parse代替。
uj5u.com熱心網友回復:
一種方法是要求 spark 將所有列轉換為您期望的新型別。我不確定它是否適用于所有型別的轉換,但它適用于許多情況:
List<Column> columns = Arrays
.stream(newSchema.fields())
.map(field -> col(field.name()).cast(field.dataType()))
.collect(Collectors.toList());
Dataset<Row> newResult = result.select(columns.toArray(new Column[0]));
另一種方法是依靠 spark 將模式應用于 csv 檔案的方式,但這需要將資料寫入磁盤,因此我不推薦該選項。
result.write().csv("somewhere");
Dataset<Row> newResult = spark.read().schema(newSchema).csv("somewhere");
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/350963.html
