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

m1m5dgzv  于 2023-01-02  发布在  Scala
关注(0)|答案(2)|浏览(117)

我是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 select之前,我是否需要先进行验证?

6gpjuf90

6gpjuf901#

可以只使用可变参数:

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(_ || _))
c7rzv4ha

c7rzv4ha2#

答案很好,但缺少另一个简单的解决方案:

val columns = Array("name", "age")
val df2 = df.select(columns.map(col): _*)

相关问题