我正在使用Scala编写一个Spark项目,在该项目中,我需要根据“演示”数据集进行一些计算。我正在使用databricks平台。
我需要将我的数据框的第二列(trainingCoordDataFrame)传递到列表中。列表的类型必须为List [Int]。
数据帧如下所示:
> +---+---+---+---+
> |_c0|_c1|_c2|_c3|
> +---+---+---+---+
> |1 |0 |0 |a |
> |11 |9 |1 |a |
> |12 |2 |7 |c |
> |13 |2 |9 |c |
> |14 |2 |4 |b |
> |15 |1 |3 |c |
> |16 |4 |6 |c |
> |17 |3 |5 |c |
> |18 |5 |3 |a |
> |2 |0 |1 |a |
> |20 |8 |9 |c |
> |3 |1 |0 |b |
> |4 |3 |4 |b |
> |5 |8 |7 |b |
> |6 |4 |9 |b |
> |7 |2 |5 |a |
> |8 |1 |9 |a |
> |9 |3 |6 |a |
> +---+---+---+---+
我正在尝试使用以下命令创建我想要的列表:
val trainingCoordList = trainingCoordDataFrame.select("_c1").collect().map(each => (each.getAs[Int]("_c1"))).toList
来自编译器的消息是这样的:
java.lang.ClassCastException:无法将java.lang.String强制转换为 java.lang.Integer
请注意,过程是:
1)。将数据集从本地PC上传到数据块(因此无法使用标准数据)。
val mainDataFrame = spark.read.format("csv").option("header", "false").load("FileStore/tables/First_Spacial_Dataset_ByAris.csv")
2)创建数据框。 (第一步:随机拆分主数据框。第二步:删除不必要的列)
val Array(trainingDataFrame,testingDataFrame) = mainDataFrame.randomSplit(Array(0.8,0.2)) //step one
val trainingCoordDataFrame = trainingDataFrame.drop("_c0", "_c3") //step two
3)创建列表。 <-这是错误的命令。
达到我想要的结果的正确方法是什么?
答案 0 :(得分:2)
我认为有几种方法可以解决此问题。
A)为CSV定义架构:
例如:
val customSchema = StructType(Array(
StructField("_c0", IntegerType),
StructField("_c1", IntegerType),
StructField("_c2", IntegerType),
StructField("_c3", StringType)))
当您阅读CSV时,将模式选项与我们之前创建的StructType一起添加
val mainDataFrame = spark.read.format("csv").option("header", "false").schema(customSchema).load("FileStore/tables/First_Spacial_Dataset_ByAris.csv")
现在,如果我们查看mainDataFrame.printSchema()
命令的输出,我们将看到根据您的用例键入了列:
root
|-- _c0: integer (nullable = true)
|-- _c1: integer (nullable = true)
|-- _c2: integer (nullable = true)
|-- _c3: string (nullable = true)
这意味着我们实际上可以运行您的原始命令而不会出现错误。
trainingCoordDataFrame.select("_c2").map(r => r.getInt(0)).collect.toList
B)将整个列转换为Int
引用列本身而不是列名,然后将该列转换为IntegerType。现在列类型为Int,您可以在之前失败的地方再次使用getInt:
trainingCoordDataFrame.select($"_c2".cast(IntegerType)).map(r => r.getInt(0)).collect.toList
C)分别转换每个值
使用地图将每个单独的值强制转换为或检索为String,然后将其强制强制转换为Int
trainingCoordDataFrame.select("_c2").map(r => r.getString(0).toInt).collect.toList
答案 1 :(得分:1)
该列的值是string类型的,因此请将该列读为string并使用scala的string.toInt方法。 在这个地方施展演员肯定是错误的。
val trainingCoordList = trainingCoordDataFrame.select("_c1").collect().map(each => each.getAs[String]("_c1").toInt).toList
或将Dataset API与自定义架构一起使用,例如与元组