【问题标题】:How to match Schema of two Data Frames如何匹配两个数据框的架构
【发布时间】:2019-06-13 11:04:50
【问题描述】:

我在表中保存了默认列名,我想将保存在表中的列名与我将在 CSV 文件中接收到的列名相匹配。

以下代码的结果是:

如果文件具有与表中存储的相同的列名以进行匹配,则执行一些处理,否则退出并抛出不匹配架构的电子邮件。

这是我的代码:

val expectedschemadf = spark.sql(s"""SELECT columnname FROM  table""").columns
val receivedschemadf = spark.table(vendorfile.toString).columns

if(expectedschemadf.size == receivedschemadf.size)
{
  breakable {for(i<-0 to expectedschemadf.size-1 by 1)
  {
    if (!(receivedschemadf contains expectedschemadf(i)))
    {
      print("fail")
      break
    }

  }
  }
}
else(print("fail"))

我想要的结果:

我想将上面的 for 循环自动化到一些预定义的函数中。

【问题讨论】:

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


    【解决方案1】:

    以下是检查两个数据框架构的示例代码

    scala> val df1 = Seq((1,"a", 1.5)).toDF
    df1: org.apache.spark.sql.DataFrame = [_1: int, _2: string ... 1 more field]
    
    scala> df1.printSchema
    root
     |-- _1: integer (nullable = false)
     |-- _2: string (nullable = true)
     |-- _3: double (nullable = false)
    
    scala> val df2 = Seq((100,"x", 1231)).toDF
    df2: org.apache.spark.sql.DataFrame = [_1: int, _2: string ... 1 more field]
    
    scala> df2.printSchema
    root
     |-- _1: integer (nullable = false)
     |-- _2: string (nullable = true)
     |-- _3: integer (nullable = false)
    
    
    scala> df1.schema == df2.schema
    res7: Boolean = false
    
    scala> val df3 = Seq((100,"x", 123.1)).toDF
    df3: org.apache.spark.sql.DataFrame = [_1: int, _2: string ... 1 more field]
    
    scala> df3.printSchema
    root
     |-- _1: integer (nullable = false)
     |-- _2: string (nullable = true)
     |-- _3: double (nullable = false)
    
    
    scala> df1.schema == df3.schema
    res9: Boolean = true
    

    【讨论】:

    • rjshkrmara:感谢您分享您的帮助。基本上我已经完成了你提到的模式检查部分,但现在我想比较列名而不是数据类型。
    • like:我已将列名存储在 hive 的表中,然后需要将这些名称与文件头进行比较。如果文件头包含与表中存储的列相同的名称,则继续,否则中断工作。
    • 只要在 DF 中获取输入文件的 dtypes。如果您采用元组的第一个变体,它应该给您列名列表,第二个应该有类型。您可以将您的表整体放入另一个序列并匹配序列
    【解决方案2】:

    我没有在环境中运行此代码,但这通常是如何将列的名称放入 seq 和 Seq.equals 应该返回 true,如果序列的顺序和成员相同,如果有则返回 false差异。

    val tableSeq = Seq("name","address","zip") // simulating a seq that you can retrive from your table 
    val inputdf = spark.read.json("path") // reading some external data into dataframe
    val columnListUnzipped = inputdf.dtypes.unzip // unzip will give tupple of column name and type
    val columnList= columnListUnzipped._1 // get all column names as a seq
    val isEqual= tableSeq.euqals(columnList) // compare 2 sequences with using equal as provided by Scala
    

    【讨论】:

    • 谢谢 Aaron:我已经更新了我的问题,我想自动化我的代码
    • 不确定您还需要什么.. 上面的代码应该可以完成您想要完成的工作
    【解决方案3】:

    这就是我完成任务的方式。

    val expectedCol = dfMetaDataFileTracker.select("COLUMNNAME").collect().map(_.getString(0)).sorted.toList.map(_.toUpperCase()) 
    val receivedCol = dfVendorFile.columns.sorted.toList.map(_.toUpperCase())
      if ((expectedCol.length == receivedCol.length) && (expectedCol.equals(receivedCol))) 
      {
        println("file schema matched with the expected schema!")
        break
      }
      else {
        println("file schema does not matched with the expected schema!")
        break        
      }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-16
      • 2019-06-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多