我正在使用带有Hive的Spark 1.3.1并且有一个行对象,它是一系列传递给Vecors.dense构造函数的双精度数组,但是当我通过
将一行转换为数组时SparkDataFrame.map{r => r.toSeq.toArray}
所有类型信息都丢失了,我找回了[Any]类型的数组。我无法使用
将此对象转换为doubleSparkDataFrame.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需要转换为双精度数组时,这非常繁琐。
任何明确索引行对象的方法?
答案 0 :(得分:10)
让我们一起看看你的代码块
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
不是一个演员..你可以在一个字符串上或在你的情况下一个整数,它将改变变量类型的实例。如果您在Int上调用_.toDouble
,则更像是在执行Double.parseDouble(inputInt)
。
_.asInstanceOf[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)
}
答案 1 :(得分:3)
你应该使用java中的Double.parseDouble。
<div class="col-sm-12 primary" ng-if="isAuthenticated">
<div class="col-sm-2"><a href="#" class="ui-btn ui-shadow ui-corner-all personal">PERSONALINFO</a></div>
<div class="col-sm-2"><a href="login.php" class="ui-btn ui-shadow ui-corner-all">LOGOUT</a></div>
</div>
答案 2 :(得分:0)
有一个类似的,更难的问题,因为我的功能并非都是Double。以下是我能够从我的DataFrame(从Hive表中拉出)转换为LabeledPoint RDD的方法:
val loaff = oaff.map(r =>
LabeledPoint(if (r.getString(classIdx)=="NOT_FRAUD") 0 else 1,
Vectors.dense(featIdxs.map(r.get(_) match {case null => Double.NaN
case d: Double => d
case l: Long => l}).toArray)))