Spark Dataframe架构定义使用带有案例类和列名别名的反射

时间:2016-12-20 14:58:21

标签: json scala apache-spark reflection case-class

我的Spark Scala脚本遇到了一个小问题。基本上我有原始数据,我在分组和计数等时进行聚合,我希望将输出保存为特定的JSON格式。

修改

我试图简化问题并重新编写:

当我从源数据框中选择具有Array[org.apache.spark.sql.Column]的数据时,其中列名称具有别名,然后在尝试将行映射到案例类时使用列名(或实际上是索引)作为变量,然后我得到“任务不可序列化”例外。

var dm = sqlContext.createDataFrame(Seq((1,"James"),(2,"Anna"))).toDF("id", "name")

val cl = dm.columns
val cl2 = cl.map(name => col(name).as(name.capitalize))
val dm2 = dm.select(cl2:_*)
val n = "Name"
case class Result(Name:String)
val r = dm2.map(row => Result(row.getAs(n))).toDF

第二部分或问题,我实际上需要最终的模式是这些Result类对象的数组。我还没弄明白,怎么做也是这样。预期结果应该具有如下模式:

    case class Test(var FilteredStatistics: Array[Result])
    val t = Test(Array(Result("Anna"), Result("James")))

    val t2 = sc.parallelize(Seq(t)).toDF

    scala> t2.printSchema
    root
     |-- FilteredStatistics: array (nullable = true)
     |    |-- element: struct (containsNull = true)
     |    |    |-- Name: string (nullable = true)

TL; DR

  1. 当dataframe列有别名并且变量用于列名时,如何将数据框行映射到案例类对象?

  2. 如何将这些案例类对象添加到数组中?

1 个答案:

答案 0 :(得分:0)

序列化问题:这里的问题是 <option value="<?php echo $ledger_id.":".$ledger_credit;?>"><?php echo $ledger_name;?></option> function setDebit(ele){ var Value = document.getElementById("ledger").val(); var Parts = Value.split(":"); var LedgerID = Parts[0]; var LedgerCredit = Parts[1]; } :它在传递给RDD转换(val n = "Name")的匿名函数中使用,这使得Spark关闭了变量和包含它的范围,其中还包含类型为dm2.map(...)的{​​{1}},因此它不可序列化。

解决方案很简单 - 内联cl2(获取Array[Column]),或将其放在Serializable上下文(不包含任何非可序列化成员的对象或类)中。