在Scala Spark中计算百分比时,我试图使用Option case类来处理零分母。RDD的集合如下所示:
val counties = Array("New+York", "Bronx","Kings","Queens","Richmond")
val base_url = "https://health.data.ny.gov/resource/xdss-u53e.json?County="
val urls = counties.map(a => base_url+a)
val results = urls.map(u => scala.io.Source.fromURL(u).mkString)
val data_rdd = spark.read.json(sc.parallelize(results)).rdd.map(r => (r(4).toString.slice(0,10), r(0).toString,r(3).toString.toInt,r(5).toString.toInt))
我想做的是返回一个元组(日期、状态、百分比(,其中百分比是通过将第三个元素除以第四个元素来计算的(即使用第一个Int除以第二个Int(。然而,由于有些除数为零,我确实需要使用Option case类来处理这些情况,但我一直在纠结如何使用Scala Spark来做到这一点。
以下是我尝试过的:
data_rdd.map{ case (a,b,c,d) => (a,b,c/d)
case _ => (a,b,0)}
这个代码给我一个错误:
<console>:28: error: not found: value a
case _ => (a,b,0)}
有人能帮我找出一种使用选项事例类处理零除数的方法吗?非常感谢!
您可以使用scala.util.Try
。基本上,你可以给它一个可能失败的输入,然后把它变成一个选项。一个简化的例子如下:
import org.apache.spark.sql._
import spark.implicits._
import scala.util.Try
val columnNames = Seq("String", "Int1", "Int2")
val df = Seq(
("Alex", 3, 4),
("John", 1, 2),
("Alice", 7, 0),
("Mark", 5, -3)
).toDF(columnNames: _*)
val output = df.map{
row => {
// Dividing int1 by int2
val division = Try(row.getInt(1) / row.getInt(2)).toOption
// Creating a new row with an extra element: division
(row.getString(0), row.getInt(1), row.getInt(2), division)
}
}.toDF(columnNames :+ "division": _*)
output.show
+------+----+----+--------+
|String|Int1|Int2|division|
+------+----+----+--------+
| Alex| 3| 4| 0|
| John| 1| 2| 0|
| Alice| 7| 0| null|
| Mark| 5| -3| -1|
+------+----+----+--------+
这种划分在发生时不会失败,它只是在您的行中创建一个null
条目。
我使用了Dataframes
,因为它是我首选的API,但您也可以对RDD执行同样的操作。
希望这能有所帮助!