我将 Spark 1.3.1 与 Hive 一起使用,并且有一个行对象,它是一系列要传递给 Vecors.dense 构造函数的 double 数,但是当我通过将 Row 转换为数组时
SparkDataFrame.map{r => r.toSeq.toArray}
所有类型信息都丢失了,我得到了一个 [Any] 类型的数组。我无法使用这个对象来加倍使用
SparkDataFrame.map{r =>
val array = r.toSeq.toArray
array.map(_.toDouble)
} // Fails with value toDouble is not a member of any
一样
SparkDataFrame.map{r =>
val array = r.toSeq.toArray
array.map(_.asInstanceOf[Double])
} // Fails with java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Double
我看到 Row 对象有一个 API,它支持通过以下方式获取特定元素作为类型:
SparkDataFrame.map{r =>
r.getDouble(5)}
但是,无法将 java.lang.Integer 失败的事件转换为 java.lang.Double
我发现的唯一解决方法如下:
SparkDataFrame.map{r =>
doubleArray = Array(r.getInt(5).toDouble, r.getInt(6).toDouble)
Vectors.dense(doubleArray) }
但是,当需要将索引 5 到 1000 转换为 double 数组时,这非常乏味。
有什么方法可以明确索引行对象吗?
最佳答案
让我们逐个查看您的代码块
SparkDataFrame.map{r =>
val array = r.toSeq.toArray
val doubleArra = array.map(_.toDouble)
} // Fails with value toDouble is not a member of any
Map 返回最后一个语句作为类型(即,Scala 中的任何函数都有一种隐含的返回,最后一个结果是您的返回值)。您的最后一条语句是 Unit 类型(如 Void).. 因为将变量分配给 val 没有返回。要解决这个问题,请取出作业(这有一个好处是要阅读的代码更少)。
SparkDataFrame.map{r =>
val array = r.toSeq.toArray
array.map(_.toDouble)
}
_.toDouble
不是强制转换..您可以在字符串或整数上执行此操作,它会更改变量类型的实例。如果您调用_.toDouble
在 Int 上,它更像是在做 Double.parseDouble(inputInt)
._.asInstanceOf[Double]
将是一个 Actor ..如果您的数据确实是 double ,则会更改类型。但不确定您是否需要在此处转换,如果可以,请避免转换。更新
所以你把代码改成了这个
SparkDataFrame.map{r =>
val array = r.toSeq.toArray
array.map(_.toDouble)
} // Fails with value toDouble is not a member of any
您在 SparkDataFrame 的一个节点上调用 toDouble。显然它不是具有 toDouble 方法的东西。即它不是 Int、String 或 Long。
如果这有效
SparkDataFrame.map{r =>
doubleArray = Array(r.getInt(5).toDouble, r.getInt(6).toDouble)
Vectors.dense(doubleArray) }
但是你需要做 5 到 1000 .. 为什么不做
SparkDataFrame.map{r =>
val doubleArray = for (i <- 5 to 1000){
r.getInt(i).toDouble
}.toArray
Vectors.dense(doubleArray)
}
关于scala - 将 Spark Row 转换为类型化的 double 组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30354483/