Scala 将RDD[List[AnyRef]]转换为RDD[List[String,Date,String,String]]
我想设置RDD的返回类型。但它是RDD[List[AnyRef]]。 因此,我无法直接指定任何内容。 像 这将返回RDD[List[String,Date,String,String]]类型的RDD,但它是RDD[List[AnyRef]] 编辑Scala 将RDD[List[AnyRef]]转换为RDD[List[String,Date,String,String]],scala,apache-spark,rdd,Scala,Apache Spark,Rdd,我想设置RDD的返回类型。但它是RDD[List[AnyRef]]。 因此,我无法直接指定任何内容。 像 这将返回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:1
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类型。
这个问题的解决办法是:
这里有一个小例子,它导致了同样的问题(我省略了
日期
,用字符串
,这不是重点):
以下是恢复类型的方法:
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且具有预期类型的列表,则分部函数将永远不会失败。下面是一个导致相同问题的小示例(我省略了
Date
,将其替换为String
,这不是重点):
以下是恢复类型的方法:
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且具有预期类型的列表,则分部函数将永远不会失败。通过查看您的,您似乎在将RDD转换为dataframe时遇到了问题。已经正确地回答了将java.util.Date
转换为java.sql.Date
的问题,这将解决您的问题
首先,列表
不能像对待元组一样,对列表中的每个元素都有单独的数据类型<代码>列表
只有一个数据类型,如果使用混合数据类型,则列表的数据类型表示为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
as
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|
+------------+---+---+---+
我希望通过查看您的,您在将rdd转换为数据帧时遇到了问题,答案会有所帮助。已经正确地回答了将java.util.Date
转换为java.sql.Date
的问题,这将解决您的问题
首先,列表
不能像对待元组一样,对列表中的每个元素都有单独的数据类型<代码>列表
只有一个数据类型,如果使用混合数据类型,则列表的数据类型表示为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
as
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|
+------------+---+---+---+
我希望答案是有帮助的请显示您需要的完整输入和输出的列表更新问题!!谢谢。你可能是指
列表[(日期、字符串、长字符串)]
<代码>列表[Date,String,Long,String]不是有效的类型(与通常的列表定义不同)。强制转换运算符作为安装的或模式匹配过滤器有什么问题?请显示所需的完整输入和输出的一个列表更新问题!!谢谢。你可能是指列表[(日期、字符串、长字符串)]
<代码>列表[Date,String,Long,String]
不是有效的类型(与通常的列表定义不同)。强制转换操作符作为
或模式匹配过滤器的安装有什么问题?我正在将我的rdd列表转换为平面列表,因此列表(2016年9月13日星期二02:44:31 PDT,下午12点,ri)
转换为2016年9月13日星期二02:44:31 PDT
,现在按照上述说明,我可以将部分函数与一组4一起使用,并使其类似于(2016年9月13日星期二02:44:31 PDT,2016年12月12日下午)
?但我不知道如何应用偏函数。非常感谢。你想“弄明白”什么?将最后一个代码片段保持原样,将类型替换为您想要的任何类型(在您的示例中:a:Date,b:String,c:Integer,d:String
),从四个值构建一个正确类型的元组。在那之后,尽量不要丢失任何类型。我不太明白这些非类型化的数据最初是如何在RDD中结束的。有效!!谢谢!!在这里,我正在将我的rdd列表转换为平面列表,因此列表(2016年9月13日星期二02:44:31,下午,12点,国际扶轮)
被转换为2016年9月13日星期二02:44:31,星期二02:44:31
,现在根据上面的描述,我可以使用带有4束的部分函数,并使其类似(2016年9月13日星期二02:44:31,下午,12点,国际扶轮)
?但我不知道如何应用偏函数。非常感谢。你想“弄明白”什么?将最后一个代码片段保持原样,将类型替换为您想要的任何类型(在您的示例中:a:Date,b:String,c:Integer,d:String
),从四个值构建一个正确类型的元组。在那之后,尽量不要丢失任何类型。我不太明白这些非类型化的数据最初是如何在RDD中结束的。有效!!谢谢