Spark 2.2 Scala DataFrame从字符串数组中选择,捕获错误

时间:2017-12-07 17:45:54

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

我是SparkSQL / Scala的新手,我正在努力完成一些看似简单的任务。

我正在尝试从Scala字符串数组构建一些动态SQL。我正在尝试在我的DataFrame中重新键入一些列,但我不知道在运行时我需要重新键入哪些列,我可以看到DataFrame中的列集。所以我试着这样做:

val cols = df.columns
val typedCols = cols.map( c => getTypedColumn(c) )
df.select( ...)  or df.selectExpr(...) // how to invoke this with vals from my string array??

typedCols最终会成为一个字符串数组,其值如下:

["a", "cast(b as int) b", "c"]

我是否需要首先从该数组创建一个以逗号分隔的大字符串?

因此,假设这会起作用,我会调用select语句,它会将我的DataFrame转换为具有所需类型的新DataFrame。但是,DataFrame中的某些记录会出错,并且无法尝试重新键入。

如何获得DataFrame结果,其中包含所有通过输入的好记录,然后将所有错误记录丢弃到某种错误桶中?在尝试DataFrame选择之前,我是否需要先进行验证传递?

1 个答案:

答案 0 :(得分:1)

您可以使用可变参数:

val df = Seq(("a", "1", "c"), ("foo", "bar", "baz")).toDF("a", "b", "c")
val typedCols = Array("a", "cast(b as int) b", "c")
df.selectExpr(typedCols: _*).show

+---+----+---+
|  a|   b|  c|
+---+----+---+
|  a|   1|  c|
|foo|null|baz|
+---+----+---+

但我个人更喜欢专栏:

val typedCols = Array($"a", $"b" cast "int", $"c")
df.select(typedCols: _*).show
  

如何获得DataFrame结果,其中包含所有通过输入的好记录,然后将所有错误记录丢弃到某种错误桶中?

cast失败的数据为NULL。要查找好的记录,请使用na.drop

val result = df.selectExpr(typedCols: _*)
val good = result.na.drop()

要查找错误检查,如果有NULL

import org.apache.spark.sql.functions.col

val bad = result.where(result.columns.map(col(_).isNull).reduce(_ || _))

获取无与伦比的数据:

  • 如果typedColsSeq[Column],您可以

    df.where(typedCols.map(_.isNull).reduce(_ || _))  
    
  • 如果typedColsSeq[String],您可以:

    import org.apache.spark.sql.functions.expr
    
    df.where(typedCols.map(expr(_).isNull).reduce(_ || _))