我是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选择之前,我是否需要先进行验证传递?
答案 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(_ || _))
获取无与伦比的数据:
如果typedCols
为Seq[Column]
,您可以
df.where(typedCols.map(_.isNull).reduce(_ || _))
如果typedCols
为Seq[String]
,您可以:
import org.apache.spark.sql.functions.expr
df.where(typedCols.map(expr(_).isNull).reduce(_ || _))