Scala RDD中的数据类型似乎是java.lang.Long,但map函数给出了一个类型不匹配错误

Scala RDD中的数据类型似乎是java.lang.Long,但map函数给出了一个类型不匹配错误,scala,apache-spark,Scala,Apache Spark,这种混乱可能是由于我对Scala的无知 scala> spark.range(2).toDF("number").rdd.map(x => x(0).getClass).collect res155: Array[Class[_]] = Array(class java.lang.Long, class java.lang.Long) 显然,这些类型是长的。不幸的是,当我尝试映射函数时,map()似乎需要一个字符串: scala> spark.range(2).toDF("n

这种混乱可能是由于我对Scala的无知

scala> spark.range(2).toDF("number").rdd.map(x => x(0).getClass).collect
res155: Array[Class[_]] = Array(class java.lang.Long, class java.lang.Long)
显然,这些类型是长的。不幸的是,当我尝试映射函数时,map()似乎需要一个字符串:

scala> spark.range(2).toDF("number").rdd.map(x => x(0)+22).collect
<console>:25: error: type mismatch;
 found   : Int(22)
 required: String
   spark.range(2).toDF("number").rdd.map(x => x(0)+22).collect
                                                   ^
scala>spark.range(2).toDF(“number”).rdd.map(x=>x(0)+22).收集
:25:错误:类型不匹配;
发现:Int(22)
必需:字符串
spark.range(2).toDF(“number”).rdd.map(x=>x(0)+22).收集
^
发生了什么事?一位同事指给我看Spark文档,我们有

。。。在Spark 2.0中,数据帧只是Scala和Java API中的行数据集。这些操作也称为“非类型化转换”,与强类型Scala/Java数据集附带的“类型化转换”不同


然而,这似乎与问题无关,因为getClass()的结果似乎是java.lang.Long。

问题在于,仅使用
x(0)
访问
行中的元素(映射函数中的
x
)将导致
任何
作为数据类型。相反,当使用
getAs
访问值时,告诉Spark它是一个

spark.range(2).toDF("number").rdd.map(x => x.getAs[Long](0)).collect
您可以使用列名而不是索引,以使其更清晰:

spark.range(2).toDF("number").rdd.map(x => x.getAs[Long]("number")).collect
更好的做法是将数据帧转换为数据集而不是rdd:

spark.range(2).toDF("number").as[Long].collect
map()似乎需要一个字符串:

scala> spark.range(2).toDF("number").rdd.map(x => x(0)+22).collect
<console>:25: error: type mismatch;
 found   : Int(22)
 required: String
   spark.range(2).toDF("number").rdd.map(x => x(0)+22).collect
                                                   ^
映射
不需要
字符串
+
需要。正如拉梅什的回答所说,
x(0)
具有类型
Any
。虽然不能向
任何
中添加数字,但可以添加
字符串
。随着时间的推移,有人要求删除此转换,因为实际上很少需要它,但它仍然存在