我的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 :
当dataframe列有别名并且变量用于列名时,如何将数据框行映射到案例类对象?
如何将这些案例类对象添加到数组中?
答案 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上下文(不包含任何非可序列化成员的对象或类)中。