首页 > 解决方案 > 如何将数据框转换为列表(Scala)?

问题描述

我想将包含 Double 值的 Dataframe 转换为 List 以便我可以使用它来进行计算。您有什么建议,以便我可以采用正确的类型 List(即 Double)?

我的方法是这样的:

var newList = myDataFrame.collect().toList 

但它返回一个类型List[org.apache.spark.sql.Row]我不知道它到底是什么!

是否可以忘记该步骤并简单地将我的 Dataframe 传递到函数中并从中进行计算?(例如,我想将其第二列的第三个元素与特定的双精度进行比较。是否可以直接从我的 Dataframe 中这样做?

不惜一切代价,我必须每次都了解如何创建正确的类型列表!

编辑:

输入数据框:

+---+---+ 
|_c1|_c2|
+---+---+ 
|0  |0  | 
|8  |2  | 
|9  |1  | 
|2  |9  | 
|2  |4  | 
|4  |6  | 
|3  |5  | 
|5  |3  | 
|5  |9  | 
|0  |1  | 
|8  |9  | 
|1  |0  | 
|3  |4  |
|8  |7  | 
|4  |9  | 
|2  |5  | 
|1  |9  | 
|3  |6  |
+---+---+

转换后的结果:

List((0,0), (8,2), (9,1), (2,9), (2,4), (4,6), (3,5), (5,3), (5,9), (0,1), (8,9), (1,0), (3,4), (8,7), (4,9), (2,5), (1,9), (3,6))

但是 List 中的每个元素都必须是 Double 类型。

标签: scalalistapache-sparkdataframe

解决方案


你可以转换你需要的库Double并将其转换为 RDD 和collect

如果您有无法解析的数据,那么您可以在将其转换为双倍之前使用 udf 进行清理

val stringToDouble = udf((data: String) => {
  Try (data.toDouble) match {
    case Success(value) => value
    case Failure(exception) => Double.NaN
  }
})

 val df = Seq(
   ("0.000","0"),
   ("0.000008","24"),
   ("9.00000","1"),
   ("-2","xyz"),
   ("2adsfas","1.1.1")
 ).toDF("a", "b")
  .withColumn("a", stringToDouble($"a").cast(DoubleType))
  .withColumn("b", stringToDouble($"b").cast(DoubleType))

在此之后,您将获得输出为

+------+----+
|a     |b   |
+------+----+
|0.0   |0.0 |
|8.0E-6|24.0|
|9.0   |1.0 |
|-2.0  |NaN |
|NaN   |NaN |
+------+----+

要得到Array[(Double, Double)]

val result = df.rdd.map(row => (row.getDouble(0), row.getDouble(1))).collect()

结果将是Array[(Double, Double)]


推荐阅读