当前位置: 首页 > 知识库问答 >
问题:

如何用嵌套的案例类模式模拟Spark Scala DataFrame?

裴理
2023-03-14

我如何创建/模拟Spark Scala数据帧与一个案例类嵌套在顶层?

root
 |-- _id: long (nullable = true)
 |-- continent: string (nullable = true)
 |-- animalCaseClass: struct (nullable = true)
 |    |-- name: string (nullable = true)
 |    |-- gender: string (nullable = true)

我目前正在单元测试一个在上述模式中输出数据帧的函数。为了检查相等性,我使用了toDF(),不幸的是,它给出了一个在模拟数据帧中的“_id”为nullable=true的模式,从而使测试失败(注意,函数的“实际”输出对所有内容都为nullable=true)。

我还尝试以不同的方式创建模拟数据帧,这导致了错误:https://pastebin.com/WtxtgMJA

以下是我在这种方法中尝试的内容:

import org.apache.spark.sql.Encoders
val animalSchema = Encoders.product[AnimalCaseClass].schema

val schema = List(
  StructField("_id", LongType, true),
  StructField("continent", StringType, true),
  StructField("animalCaseClass", animalSchema, true)
)

val data = Seq(Row(12345L, "Asia", AnimalCaseClass("tiger", "male")), Row(12346L, "Asia", AnimalCaseClass("tigress", "female")))

val expected = spark.createDataFrame(
  spark.sparkContext.parallelize(data),
  StructType(schema)
)

对于那些toDF默认设置为false的字段,我必须使用这种方法使其为null。

如何使用与模拟函数的输出相同的模式创建数据帧,并声明也可以是case类的值?

共有1个答案

越景天
2023-03-14

从你提供的日志中,你可以看到

原因:java。RuntimeException:模型。AnimalCaseClass不是结构的架构的有效外部类型

这意味着您正试图将AnimalCaseClass的对象类型插入到struct的数据类型中

import org.apache.spark.SparkConf
import org.apache.spark.sql.internal.SQLConf
import org.apache.spark.sql.types.{LongType, StringType, StructField, StructType}
import org.apache.spark.sql.SparkSession

case class AnimalCaseClass(name: String, gender: String)

object Test extends App {

  val conf: SparkConf = new SparkConf()
  conf.setAppName("Test")
  conf.setMaster("local[2]")
  conf.set("spark.sql.test", "")
  conf.set(SQLConf.CODEGEN_FALLBACK.key, "false")

  val spark: SparkSession = SparkSession.builder().config(conf).enableHiveSupport().getOrCreate()

  // ** The relevant part **
  import org.apache.spark.sql.Encoders
  val animalSchema = Encoders.product[AnimalCaseClass].schema

  val expectedSchema: StructType = StructType(Seq(
    StructField("_id", LongType, true),
    StructField("continent", StringType, true),
    StructField("animalCaseClass", animalSchema, true)
  ))

  import spark.implicits._
  val data = Seq((12345L, "Asia", AnimalCaseClass("tiger", "male")), (12346L, "Asia", AnimalCaseClass("tigress", "female"))).toDF()

  val expected = spark.createDataFrame(data.rdd, expectedSchema)

  expected.printSchema()

  expected.show()

  spark.stop()
}
 类似资料:
  • Alpha-父级,子级为beta 贝塔-阿尔法的孩子,查理 Charlie-有一个列表,通常在制作中会被洗牌 AlphaTest[需要此测试的帮助]-想尝试不同的洗牌变体,看看alpha/beta会如何反应。 目标是用不同的组合测试Alpha/Beta。不知道最好的方法是什么?这正是复制的代码。也可以更改设置以方便测试。尝试了不同的变体,但没有任何效果。非常感谢您的帮助。 我不确定,我尝试了一堆方

  • 我试图模拟一个单例类(SessionDataManager),通过调用静态getInstance()方法获得一个实例,但所有尝试似乎都返回null。 我试过了

  • 我需要使我的输出像预期的输出一样。我试图添加符号,但输出不像预期的输出 这是我的代码:

  • 问题内容: 我有四个让我们说A,B,C,D的类,每个类都从另一个调用方法。 现在我已经模拟了类A,并且想模拟使用嘲笑的方法 并希望在递归方法调用上获取“ foo” 应该回来 我试过了 when(a.getB()。getC()。getD())。thenReturn(“ foo”); 但是得到了nullPointerException 然后我尝试 doReturn(“ foo”)。when(a.get

  • 我有4个类让说A,B,C,D,每一个调用的方法从另一个。 现在我已经模拟了类A,并想使用mockito模拟一个方法 但得到nullPointerException 然后我试着 doReturn(“foo”).When(A.getb().getc().getd()); 但我不能一次就做到吗?如有任何帮助,我们将不胜感激。

  • 我对ScalaMock和嘲笑都是新手。我试图测试一个方法,它调用另一个(mocked)类中的方法,然后在返回的对象上调用方法。 详细资料: 所以我使用ScalaTest,这个测试涉及到五个类... 我正在测试的子指令 在测试中必须被嘲笑的机器 构造机器对象所需的寄存器 我创建为原始机器类的MockableMachine没有空构造函数,因此(据我所知)无法模拟 最后是我的测试类SubInstruct