我正在尝试将现有数据框的架构更改为另一个数据框的架构。
数据框架1:
Column A | Column B | Column C | Column D
"a" | 1 | 2.0 | 300
"b" | 2 | 3.0 | 400
"c" | 3 | 4.0 | 500
数据框2:
Column K | Column B | Column F
"c" | 4 | 5.0
"b" | 5 | 6.0
"f" | 6 | 7.0
所以我想在第二个上应用第一个数据框的架构。因此,所有相同的列均保留。数据框2中不在1中的列将被删除。其他变为“NULL”。
输出
Column A | Column B | Column C | Column D
"NULL" | 4 | "NULL" | "NULL"
"NULL" | 5 | "NULL" | "NULL"
"NULL" | 6 | "NULL" | "NULL"
因此,我提出了一个可能的解决方案:
val schema = df1.schema
val newRows: RDD[Row] = df2.map(row => {
val values = row.schema.fields.map(s => {
if(schema.fields.contains(s)){
row.getAs(s.name).toString
}else{
"NULL"
}
})
Row.fromSeq(values)
})
sqlContext.createDataFrame(newRows, schema)}
现在您可以看到,由于架构包含String,Int和Double,这将不起作用。而且我所有的行都有String值。
这就是我遇到的问题,有没有办法将我的值的类型自动转换为模式?
最佳答案
如果模式是平面的,我将仅使用映射到现有模式和select
所需的列:
val exprs = df1.schema.fields.map { f =>
if (df2.schema.fields.contains(f)) col(f.name)
else lit(null).cast(f.dataType).alias(f.name)
}
df2.select(exprs: _*).printSchema
// root
// |-- A: string (nullable = true)
// |-- B: integer (nullable = false)
// |-- C: double (nullable = true)
// |-- D: integer (nullable = true)
关于scala - 将架构从一个数据框复制到另一数据框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36795680/