我使用的数据有架构更改。对于结合了新旧数据的结果dataFrame,我想要转换& a;过滤器以前在旧数据中不存在。它没有填充" null" s。我希望尽可能地对该列进行转换和过滤,即每当列退出时,我想对其进行转换和过滤;对于没有这样一列的早期数据,我只保留每一行。
问题是以下代码会生成java.lang.NullPointerException
,因为之前的数据没有" ip"柱。
val filteredData = sqlContext.sql(
s"SELECT $fieldsString FROM data $filterTerm")
.withColumn("ip",firstIp($"ip"))
.filter("`ip` not in ('30.90.30.90', '70.80.70.80')")
.filter("`ip` not like '10.%'")
" firstIp"上面的函数只是一个从数组中获取第一个IP地址的udf;它由val firstIp = udf[String, String](_.split(",")(0))
定义。我不想按架构将数据分成两部分 - 那些带有" ip"列和那些没有...但是我的目标是否可以在不分割数据的情况下实现?
答案 0 :(得分:0)
这个答案解决了问题的旧版本,它只是要求在不同的模式上使用filter
。现在这个问题已经完全改变了。
您只需检查列是否存在:
// let's create some test data
case class SchemaA(host: String)
case class SchemaB(host: String, ip: String)
val testDataA = sc.parallelize(Seq(
SchemaA("localhost"),
SchemaA("other")
)).toDF()
val testDataB = sc.parallelize(Seq(
SchemaB("localhost", "127.0.0.1"),
SchemaB("other", "192.168.0.1")
)).toDF()
def doSomething(df: DataFrame) {
val filtered = if (df.columns.contains("ip")) {
df.filter("ip in ('127.0.0.1')")
} else {
df
}
// do whatever you want after filtering...
filtered.select($"host").show()
}
doSomething(testDataA)
doSomething(testDataB)