我需要一些帮助来理解“ scala”中的迭代。我有一个具有不同类型的数据'(Int,String,Date,Long)'的数据框。我想循环读取每一行数据。 if列数据if列数据与数据类型不匹配正确的数据类型。然后我想用null更新column的值。
我已经厌倦了读取每个列的值并检查各自的数据类型,例如“ ID列是:Integer类型,AirName:String类型,Place:String类型,TakeoffDate:Date”类型。我的输入数据集是:
+-----+-------+-----+-----------+
| ID|AirName|Place|TakeoffDate|
| 1| Delta| Aus| 1/11/18|
| 2| Delta| | 10/5/19|
|Three| null| New| 15/10/2018|
| 4| JetAir| Aus| 11/6/15|
+-----+-------+-----+-----------+
这里3是字符串类型,但ID我们已经将其声明为Int类型。所以我想用null代替Three。类似的循环中的其他列。
我已经从文件中读取数据并创建了一个数据框。现在,我想检查具有相应数据类型的每一行和每一列。如果数据类型不匹配,我想将该列替换为null。
但这对我不起作用。
val myFile = sc.textFile("/FileStore/tables/Airline__2_-14f6c.txt")
import org.apache.spark.sql.types._
case class Test(ID:Int,AirName:String,Place:String,TakeoffDate:String)
val df= myFile.map(x => x.split(",") ).map( x=> Test(x(0).toInt,x(1),x(2),x(3)) ).toDF()
def isInt(in: Integer): Option[Int] = {
try {
Some(Integer.parseInt(in))
} catch {
case e: NumberFormatException => None
}
}
rows.map{
case(ID) => if (isInt(ID).isEmpty (ID,ErrorCodes.NOT_INT))
{
println("yes")
}
else ((Int)ID, None)
{
println("no")
}
}
Expected Output
+-----+-------+-----+-----------+
| ID|AirName|Place|TakeoffDate|
| 1| Delta| Aus| 1/11/18|
| 2| Delta| null| 10/5/19|
|null | null| New| null |
| 4| JetAir| Aus| 11/6/15|
+-----+-------+-----+-----------+
答案 0 :(得分:0)
我建议不要使用提供更丰富功能的数据框/数据集API,而不是使用RDD API:
import org.apache.spark.sql.functions.{trim, length, when}
val df = Seq(
("1", "Delta", "Aus", "1/11/18"),
("2", "Delta", null, "10/5/19"),
("Three", null, "New", "15/10/2018"),
("4", "JetAir", "Aus", "11/6/15"))
.toDF("ID", "AirName","Place", "TakeoffDate")
df.withColumn("ID", $"ID".cast("int"))
.withColumn("TakeoffDate",
when(
$"TakeoffDate".rlike("\\d{1,2}/\\d{1,2}/\\d{1,2}$"), $"TakeoffDate")
.otherwise(null)
)
.withColumn("Place",
when(
length(trim($"Place")) > 0, $"Place")
.otherwise(null))
.show(false)
输出:
+----+-------+-----+-----------+
|ID |AirName|Place|TakeoffDate|
+----+-------+-----+-----------+
|1 |Delta |Aus |1/11/18 |
|2 |Delta |null |10/5/19 |
|null|null |New |null |
|4 |JetAir |Aus |11/6/15 |
+----+-------+-----+-----------+
铸造
$"ID".cast("int")
:将任何字符串转换为int。如果无法进行转换,则强制转换将默认返回null。$"TakeoffDate".rlike("\\d{1,2}/\\d{1,2}/\\d{1,2}$")
:日期应具有此正则表达式中指定的格式。如果字符串匹配,则rlike返回true,否则返回false。length(trim($"Place")) > 0
:当字符串为空时,返回null,否则返回$“ Place”的值。