我Array[org.apache.spark.sql.Row]
返回sqc.sql(sqlcmd).collect()
:
Array([10479,6,10], [8975,149,640], ...)
我可以得到个人值:
scala> pixels(0)(0)
res34: Any = 10479
但它们是Any
,而不是Int
.
如何将它们提取为Int
?
最明显的解决方案不起作用:
scala> pixels(0).getInt(0)
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Int
附言。我可以做pixels(0)(0).toString.toInt
或pixels(0).getString(0).toInt
,但他们感觉不对劲......
使用getInt
应该有效。这是一个人为的例子作为概念证明
import org.apache.spark.sql._
sc.parallelize(Array(1,2,3)).map(Row(_)).collect()(0).getInt(0)
此返回 1
然而
sc.parallelize(Array("1","2","3")).map(Row(_)).collect()(0).getInt(0)
失败。因此,它看起来像是作为字符串出现的,您必须手动转换为 int。
sc.parallelize(Array("1","2","3")).map(Row(_)).collect()(0).getString(0).toInt
文档指出getInt
:
返回列 i 的值作为 int。如果值为 i 不是整数,或者如果它为 null,则此函数将引发异常。
所以,它似乎不会尝试为你投射
> Row
类(另见 https://spark.apache.org/docs/1.1.0/api/scala/index.html#org.apache.spark.sql.package)有方法getInt(i: Int)
、getDouble(i: Int)
等。
另请注意,SchemaRDD
是一个RDD[Row]
加上一个schema
,告诉您哪一列具有哪种数据类型。如果您这样做.collect()
您只会得到一个没有该信息的Array[Row]
。因此,除非您确定数据的外观,否则请从SchemaRDD
获取架构,然后收集行,然后使用正确的类型信息访问每个字段。
答案是相关的。 您不需要使用 collect,而是需要调用方法getInt
getString
和 getAs
以防数据类型复杂
val popularHashTags = sqlContext.sql("SELECT hashtags, usersMentioned, Url FROM tweets")
var hashTagsList = popularHashTags.flatMap ( x => x.getAs[Seq[String]](0))