从常规类创建Spark数据框

时间:2018-12-06 07:09:41

标签: scala apache-spark

我一直看到,当我们使用map函数时,我们可以使用case类从rdd创建一个数据框,如下所示:-

case class filematches(
row_num:Long,
matches:Long,
non_matches:Long,
non_match_column_desc:Array[String]
)

newrdd1.map(x=> filematches(x._1,x._2,x._3,x._4)).toDF()

这众所周知,效果很好!

我想知道,为什么我们在这里特别需要案例类? 使用带有参数化构造函数的普通类,我们应该能够实现相同的效果(因为它们将是val而不是私有的):-

class filematches1(
val row_num:Long,
val matches:Long,
val non_matches:Long,
val non_match_column_desc:Array[String]
)

newrdd1.map(x=> new filematches1(x._1,x._2,x._3,x._4)).toDF

在这里,我正在使用new关键字实例化该类。

上面的运行给了我错误:-

  

错误:toDF的值不是org.apache.spark.rdd.RDD [filematches1]的成员

我确定我在这里缺少案例类和常规类的一些关键概念,但是还找不到。

1 个答案:

答案 0 :(得分:0)

解决以下错误     值toDF不是org.apache.spark.rdd.RDD [...]的成员 您应该将案例类定义移出使用函数的位置。您可以参考http://community.cloudera.com/t5/Advanced-Analytics-Apache-Spark/Spark-Scala-Error-value-toDF-is-not-a-member-of-org-apache/td-p/29878了解模式的详细信息。

在您的其他查询上-案例类是语法糖,它们提供了以下附加功能

案例类不同于常规类。它们特别用于创建不可变对象。

  1. 它们具有默认的apply函数,该函数用作构造函数来创建对象。 (因此,较小的代码)

  2. case类中的所有变量默认为val类型。因此是一成不变的。这对火花世界来说是一件好事,因为所有红色都是不可变的

    案例类别的示例是 案例类Book(name:string) val book1 = Book(“ test”)

您无法更改book1.name的值,因为它是不可变的。而且您无需在此处说出新的Book()即可创建对象。

  1. 默认情况下,类变量是公共的。因此您不需要二传手和吸气剂。

此外,在比较案例类的两个对象时,将比较其结构而不是引用。

Edit:Spark使用以下类来推断模式 代码链接: https://github.com/apache/spark/blob/branch-2.4/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/ScalaReflection.scala

如果您检查。在schemaFor函数中(第719行到791行)。它将Scala类型转换为催化剂类型。我尚未添加用于处理架构案例推断的非案例类的案例。因此,每次您尝试将非案例类与推断模式一起使用时。转到其他选项,因此给出了不支持$ other类型的模式错误。

希望这会有所帮助