我想设置RDD的返回类型。但它是RDD [List [AnyRef]]。 所以我无法直接指定任何内容。 像,
val rdd2 = rdd1.filter(! _.isEmpty).filter(x => x(0) != null)
返回RDD [List [String,Date,String,String]]类型的RDD,但它是RDD [List [AnyRef]]。
修改
rdd1:
List(Sun Jul 31 10:21:53 PDT 2016, pm1, 11, ri1)
List(Mon Aug 01 12:57:09 PDT 2016, pm3, 5, ri1)
List(Mon Aug 01 01:11:16 PDT 2016, pm1, 1, ri2)
此rdd1是RDD [List [AnyRef]]类型。
现在我想要这种类型的rdd2:
RDD[List[Date, String, Long, String]]
原因是我在使用模式将RDD转换为数据框时面临日期问题。首先要解决这个问题,我必须修复RDD类型。 那个问题的解决方案是: Spark rdd correct date format in scala?
答案 0 :(得分:2)
这是一个导致相同问题的小例子(我省略了Date
,将其替换为String
,这不是重点:
val myRdd = sc.makeRDD(List(
List[AnyRef]("date 1", "blah2", (11: java.lang.Integer), "baz1"),
List[AnyRef]("date 2", "blah3", (5: java.lang.Integer), "baz2"),
List[AnyRef]("date 3", "blah4", (1: java.lang.Integer), "baz3")
))
// myRdd: org.apache.spark.rdd.RDD[List[AnyRef]] = ParallelCollectionRDD[0]
以下是恢复类型的方法:
val unmessTypes = myRdd.map{
case List(a: String, b: String, c: java.lang.Integer, d: String) => (a, b, (c: Int), d)
}
// unmessTypes: org.apache.spark.rdd.RDD[(String, String, Int, String)] = MapPartitionsRDD[1]
您只需应用一个将长度为4的列表与指定类型的元素匹配的部分函数,并从中构造出预期类型的元组。如果您的RDD确实只包含长度为4且具有预期类型的列表,则部分函数将永远不会失败。
答案 1 :(得分:2)
通过查看您的Spark rdd correct date format in scala?,您似乎在将rdd转换为数据帧时遇到问题。 Tzach已经正确回答了将java.util.Date
转换为java.sql.Date
的问题,这可以解决您的问题。
首先,List
不能为列表中的每个元素提供单独的 dataType ,就像我们对Tuples
所做的那样。 List
只有一个 dataType ,如果使用混合 dataTypes ,则列表的 dataType 表示为Any
或AnyRef
。
我猜您必须创建如下数据
val list = List(
List[AnyRef](new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy", Locale.ENGLISH).parse("Sun Jul 31 10:21:53 PDT 2016"), "pm1", 11L: java.lang.Long,"ri1"),
List[AnyRef](new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy", Locale.ENGLISH).parse("Mon Aug 01 12:57:09 PDT 2016"), "pm3", 5L: java.lang.Long, "ri1"),
List[AnyRef](new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy", Locale.ENGLISH).parse("Mon Aug 01 01:11:16 PDT 2016"), "pm1", 1L: java.lang.Long, "ri2")
)
val rdd1 = spark.sparkContext.parallelize(list)
会给出
rdd1: org.apache.spark.rdd.RDD[List[AnyRef]]
但事实上它真正的数据类型是[java.util.Date, String, java.lang.Long, String]
在查看您的其他问题时,您必须在将rdd
转换为具有dataframe
后的schema
时遇到问题
val schema =
StructType(
StructField("lotStartDate", DateType, false) ::
StructField("pm", StringType, false) ::
StructField("wc", LongType, false) ::
StructField("ri", StringType, false) :: Nil)
您可以做的是在其他问题中使用java.sql.Date
api,然后创建dataframe
val rdd1 = sc.parallelize(list).map(lis => Row.fromSeq(new java.sql.Date((lis.head.asInstanceOf[java.util.Date]).getTime)::lis.tail))
val df = sqlContext.createDataFrame(rdd1,schema)
应该给你
+------------+---+---+---+
|lotStartDate|pm |wc |ri |
+------------+---+---+---+
|2016-07-31 |pm1|11 |ri1|
|2016-08-02 |pm3|5 |ri1|
|2016-08-01 |pm1|1 |ri2|
+------------+---+---+---+
我希望答案很有帮助