如何将类型 Any List 转换为类型 Double (Scala)

How to convert a type Any List to a type Double (Scala)

我是 Scala 的新手,我想了解一些基本的东西。

首先,我需要计算DataFrame[=56]的某列的平均值 =] 并将结果用作双精度类型变量。

经过一些互联网研究后,我能够计算平均值,同时使用以下命令将其传递到 List 类型 Any 中:

val avgX_List = mainDataFrame.groupBy().agg(mean("_c1")).collect().map(_(0)).toList

其中“_c1”是我的数据框第二列。这行代码 returns 一个类型为 List[Any] 的列表。

为了将结果传递给变量,我使用了以下命令:

var avgX = avgX_List(0)

希望 var avgX 会自动键入 double,但这显然没有发生。

现在开始提问:

  1. map(_(0)) do是什么意思?我知道 map() 转换的基本定义,但我找不到这个确切参数的解释

  2. 我知道通过在命令末尾使用 .toList 方法,我的结果将是类型为 Any 的列表。有没有办法可以将其更改为包含类型 Double 元素的列表?甚至转换这个

  3. 您认为将我的 Dataframe 的列传递到 List[Double] 然后计算其元素的平均值会更合适吗?

  4. 根据我的问题,我上面展示的解决方案从任何角度来看都是正确的吗?我知道 "it is working" 不同于 "correct solution"?

综上所述,我需要计算Dataframe某列的平均值,并将结果作为double类型的变量。

注意:我是希腊人,我发现有时很难理解一些英语编码"slang"。

map(_(0))map( (r: Row) => r(0) ) 的快捷方式,后者又是 map( (r: Row) => r.apply(0) ) 的快捷方式。 apply 方法 returns Any,所以你失去了正确的类型。请尝试使用 map(_.getAs[Double](0))map(_.getDouble(0))

收集列的所有条目然后计算平均值会适得其反,因为您必须将大量数据发送到主节点,然后在这个单一的中央节点上进行所有计算。这与 Spark 的优点正好相反。

您也不需要 collect(...).toList,因为您可以直接访问第 0 个条目(无论您是从 Array 还是从 List).由于您无论如何都将所有内容折叠成一个 Row,因此您可以通过稍微重新排序方法来完全摆脱 map 步骤:

val avgX = mainDataFrame.groupBy().agg(mean("_c1")).collect()(0).getDouble(0)

使用first方法可以写得更短:

val avgX = mainDataFrame.groupBy().agg(mean("_c1")).first().getDouble(0)
#Any dataType in Scala can't be directly converted to Double.
#Use toString & then toDouble on final captured result.

#Eg-

#scala> x
#res22: Any = 1.0

#scala> x.toString.toDouble
#res23: Double = 1.0

#Note- Instead of using map().toList() directly use (0)(0) to get the final value from your resultset.


#TestSample(Scala)-

val wa = Array("one","two","two")
val wrdd = sc.parallelize(wa,3).map(x=>(x,1))
val wdf = wrdd.toDF("col1","col2")
val x = wdf.groupBy().agg(mean("col2")).collect()(0)(0).toString.toDouble

#O/p-
#scala> val x = wdf.groupBy().agg(mean("col2")).collect()(0)(0).toString.toDouble
#x: Double = 1.0