如何将类型任何列表转换为类型Double(Scala)

问题描述 投票:1回答:2

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

首先,我需要计算DataFrame的某个列的平均值,并将结果用作double类型变量。

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

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

其中“_c1”是我的数据帧的第二列。这行代码返回List类型为List [Any]的List。

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

var avgX = avgX_List(0)

希望var avgX会自动输入double类型但显然不会发生。

所以现在让问题开始:

  1. map(_(0)) do是什么?我知道map()变换的基本定义,但我无法用这个确切的论证找到解释
  2. 我知道通过在命令的末尾使用.toList方法,我的结果将是一个类型为Any的List。有没有办法我可以将其更改为包含类型Double元素的List?甚至转换这个
  3. 你认为将我的Dataframe列传递给List [Double]然后计算其元素的平均值会更合适吗?
  4. 根据我的问题,我在上面展示的解决方案在任何观点都是正确的吗?我知道“它正在发挥作用”与“正确的解决方案”不同吗?

总结一下,我需要计算一个Dataframe的某一列的平均值,并将结果作为double类型变量。

请注意:我是希腊语,我发现有时候很难理解一些英语编码“俚语”。

scala apache-spark mean databricks
2个回答
4
投票

map(_(0))map( (r: Row) => r(0) )的捷径,而map( (r: Row) => r.apply(0) )又是apply的捷径。 Any方法返回map(_.getAs[Double](0)),因此您正在丢失正确的类型。尝试使用map(_.getDouble(0))collect(...).toList代替。

收集列的所有条目然后计算平均值将极具反作用,因为您必须向主节点发送大量数据,然后在此单个中心节点上执行所有计算。这与Spark有利的完全相反。

你也不需要Array,因为你可以直接访问第0个条目(无论你是从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


1
投票
qazxswpoi
© www.soinside.com 2019 - 2024. All rights reserved.