火花:架构变化 - 变换&如果列退出,则过滤列上的数据帧;如果没有,请不要

时间:2016-08-26 16:20:23

标签: scala apache-spark apache-spark-sql spark-dataframe databricks

我使用的数据有架构更改。对于结合了新旧数据的结果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"列和那些没有...但是我的目标是否可以在不分割数据的情况下实现?

1 个答案:

答案 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)