如何将类型 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,但这显然没有发生。
现在开始提问:
map(_(0)) do
是什么意思?我知道 map()
转换的基本定义,但我找不到这个确切参数的解释
我知道通过在命令末尾使用 .toList
方法,我的结果将是类型为 Any
的列表。有没有办法可以将其更改为包含类型 Double
元素的列表?甚至转换这个
您认为将我的 Dataframe 的列传递到 List[Double] 然后计算其元素的平均值会更合适吗?
根据我的问题,我上面展示的解决方案从任何角度来看都是正确的吗?我知道 "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
我是 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,但这显然没有发生。
现在开始提问:
map(_(0)) do
是什么意思?我知道map()
转换的基本定义,但我找不到这个确切参数的解释我知道通过在命令末尾使用
.toList
方法,我的结果将是类型为Any
的列表。有没有办法可以将其更改为包含类型Double
元素的列表?甚至转换这个您认为将我的 Dataframe 的列传递到 List[Double] 然后计算其元素的平均值会更合适吗?
根据我的问题,我上面展示的解决方案从任何角度来看都是正确的吗?我知道 "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